Merge branch 'feature/remove-wrap-modes' into develop
This commit is contained in:
commit
c98ad8c948
@ -26,14 +26,14 @@ freely, subject to the following restrictions:
|
||||
#include "PolyVox/CubicSurfaceExtractor.h"
|
||||
#include "PolyVox/MarchingCubesSurfaceExtractor.h"
|
||||
#include "PolyVox/Mesh.h"
|
||||
#include "PolyVox/PagedVolume.h"
|
||||
#include "PolyVox/RawVolume.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
//Use the PolyVox namespace
|
||||
using namespace PolyVox;
|
||||
|
||||
void createSphereInVolume(PagedVolume<uint8_t>& volData, float fRadius)
|
||||
void createSphereInVolume(RawVolume<uint8_t>& volData, float fRadius)
|
||||
{
|
||||
//This vector hold the position of the center of the volume
|
||||
Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2);
|
||||
@ -60,7 +60,7 @@ void createSphereInVolume(PagedVolume<uint8_t>& volData, float fRadius)
|
||||
}
|
||||
|
||||
//Wrte the voxel value into the volume
|
||||
volData.setVoxelAt(x, y, z, uVoxelValue);
|
||||
volData.setVoxel(x, y, z, uVoxelValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,7 @@ protected:
|
||||
void initializeExample() override
|
||||
{
|
||||
// Create an empty volume and then place a sphere in it
|
||||
PagedVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
||||
RawVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
||||
createSphereInVolume(volData, 30);
|
||||
|
||||
// Extract the surface for the specified region of the volume. Uncomment the line for the kind of surface extraction you want to see.
|
||||
|
@ -26,14 +26,14 @@ freely, subject to the following restrictions:
|
||||
#include "PolyVox/CubicSurfaceExtractor.h"
|
||||
#include "PolyVox/MarchingCubesSurfaceExtractor.h"
|
||||
#include "PolyVox/Mesh.h"
|
||||
#include "PolyVox/PagedVolume.h"
|
||||
#include "PolyVox/RawVolume.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
//Use the PolyVox namespace
|
||||
using namespace PolyVox;
|
||||
|
||||
void createSphereInVolume(PagedVolume<uint8_t>& volData, float fRadius)
|
||||
void createSphereInVolume(RawVolume<uint8_t>& volData, float fRadius)
|
||||
{
|
||||
//This vector hold the position of the center of the volume
|
||||
Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2);
|
||||
@ -60,7 +60,7 @@ void createSphereInVolume(PagedVolume<uint8_t>& volData, float fRadius)
|
||||
}
|
||||
|
||||
//Wrte the voxel value into the volume
|
||||
volData.setVoxelAt(x, y, z, uVoxelValue);
|
||||
volData.setVoxel(x, y, z, uVoxelValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,7 +94,7 @@ protected:
|
||||
setShader(shader);
|
||||
|
||||
//Create an empty volume and then place a sphere in it
|
||||
PagedVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
||||
RawVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
||||
createSphereInVolume(volData, 30);
|
||||
|
||||
// Extract the surface for the specified region of the volume. Uncomment the line for the kind of surface extraction you want to see.
|
||||
|
@ -27,7 +27,7 @@ freely, subject to the following restrictions:
|
||||
|
||||
using namespace PolyVox;
|
||||
|
||||
void createSphereInVolume(PagedVolume<MaterialDensityPair88>& volData, float fRadius, uint8_t uValue)
|
||||
void createSphereInVolume(RawVolume<MaterialDensityPair88>& volData, float fRadius, uint8_t uValue)
|
||||
{
|
||||
//This vector hold the position of the center of the volume
|
||||
Vector3DInt32 v3dVolCenter = (volData.getEnclosingRegion().getUpperCorner() - volData.getEnclosingRegion().getLowerCorner()) / static_cast<int32_t>(2);
|
||||
@ -48,14 +48,14 @@ void createSphereInVolume(PagedVolume<MaterialDensityPair88>& volData, float fRa
|
||||
//then we make it solid, otherwise we make it empty space.
|
||||
if(fDistToCenter <= fRadius)
|
||||
{
|
||||
volData.setVoxelAt(x,y,z, MaterialDensityPair88(uValue, uValue > 0 ? MaterialDensityPair88::getMaxDensity() : MaterialDensityPair88::getMinDensity()));
|
||||
volData.setVoxel(x,y,z, MaterialDensityPair88(uValue, uValue > 0 ? MaterialDensityPair88::getMaxDensity() : MaterialDensityPair88::getMinDensity()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createCubeInVolume(PagedVolume<MaterialDensityPair88>& volData, Vector3DInt32 lowerCorner, Vector3DInt32 upperCorner, uint8_t uValue)
|
||||
void createCubeInVolume(RawVolume<MaterialDensityPair88>& volData, Vector3DInt32 lowerCorner, Vector3DInt32 upperCorner, uint8_t uValue)
|
||||
{
|
||||
uint8_t maxDen = MaterialDensityPair88::getMaxDensity();
|
||||
uint8_t minDen = MaterialDensityPair88::getMinDensity();
|
||||
@ -66,7 +66,7 @@ void createCubeInVolume(PagedVolume<MaterialDensityPair88>& volData, Vector3DInt
|
||||
{
|
||||
for (int x = lowerCorner.getX() ; x <= upperCorner.getX(); x++)
|
||||
{
|
||||
volData.setVoxelAt(x,y,z, MaterialDensityPair88(uValue, uValue > 0 ? maxDen : minDen));
|
||||
volData.setVoxel(x,y,z, MaterialDensityPair88(uValue, uValue > 0 ? maxDen : minDen));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,10 +24,10 @@ freely, subject to the following restrictions:
|
||||
#ifndef __OpenGLExample_Shapes_H__
|
||||
#define __OpenGLExample_Shapes_H__
|
||||
|
||||
#include "PolyVox/PagedVolume.h"
|
||||
#include "PolyVox/RawVolume.h"
|
||||
#include "PolyVox/MaterialDensityPair.h"
|
||||
|
||||
void createSphereInVolume(PolyVox::LargeVolume<PolyVox::MaterialDensityPair88>& volData, float fRadius, uint8_t uValue);
|
||||
void createCubeInVolume(PolyVox::LargeVolume<PolyVox::MaterialDensityPair88>& volData, PolyVox::Vector3DInt32 lowerCorner, PolyVox::Vector3DInt32 upperCorner, uint8_t uValue);
|
||||
void createSphereInVolume(PolyVox::RawVolume<PolyVox::MaterialDensityPair88>& volData, float fRadius, uint8_t uValue);
|
||||
void createCubeInVolume(PolyVox::RawVolume<PolyVox::MaterialDensityPair88>& volData, PolyVox::Vector3DInt32 lowerCorner, PolyVox::Vector3DInt32 upperCorner, uint8_t uValue);
|
||||
|
||||
#endif //__OpenGLExample_Shapes_H__
|
@ -58,8 +58,7 @@ public:
|
||||
protected:
|
||||
void initializeExample() override
|
||||
{
|
||||
FilePager<MaterialDensityPair88>* pager = new FilePager<MaterialDensityPair88>(".");
|
||||
PagedVolume<MaterialDensityPair88> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(g_uVolumeSideLength - 1, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1)), pager);
|
||||
RawVolume<MaterialDensityPair88> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(g_uVolumeSideLength - 1, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1)));
|
||||
|
||||
//Make our volume contain a sphere in the center.
|
||||
int32_t minPos = 0;
|
||||
|
@ -67,7 +67,7 @@ void createSphereInVolume(PagedVolume<MaterialDensityPair44>& volData, Vector3DF
|
||||
voxel.setDensity(uDensity);
|
||||
|
||||
//Wrte the voxel value into the volume
|
||||
volData.setVoxelAt(x, y, z, voxel);
|
||||
volData.setVoxel(x, y, z, voxel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,7 +127,7 @@ public:
|
||||
// Voxel position within a chunk always start from zero. So if a chunk represents region (4, 8, 12) to (11, 19, 15)
|
||||
// then the valid chunk voxels are from (0, 0, 0) to (7, 11, 3). Hence we subtract the lower corner position of the
|
||||
// region from the volume space position in order to get the chunk space position.
|
||||
pChunk->setVoxelAt(x - region.getLowerX(), y - region.getLowerY(), z - region.getLowerZ(), voxel);
|
||||
pChunk->setVoxel(x - region.getLowerX(), y - region.getLowerY(), z - region.getLowerZ(), voxel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,8 +151,7 @@ protected:
|
||||
void initializeExample() override
|
||||
{
|
||||
PerlinNoisePager* pager = new PerlinNoisePager();
|
||||
PagedVolume<MaterialDensityPair44> volData(PolyVox::Region::MaxRegion(), pager, 64);
|
||||
volData.setMemoryUsageLimit(8 * 1024 * 1024); // 8Mb
|
||||
PagedVolume<MaterialDensityPair44> volData(pager, 8 * 1024 * 1024, 64);
|
||||
|
||||
//createSphereInVolume(volData, 30);
|
||||
//createPerlinTerrain(volData);
|
||||
|
@ -27,7 +27,6 @@ freely, subject to the following restrictions:
|
||||
#include "PolyVox/MarchingCubesSurfaceExtractor.h"
|
||||
#include "PolyVox/Mesh.h"
|
||||
#include "PolyVox/RawVolume.h"
|
||||
#include "PolyVox/PagedVolume.h"
|
||||
#include "PolyVox/VolumeResampler.h"
|
||||
|
||||
#include <QApplication>
|
||||
@ -35,7 +34,7 @@ freely, subject to the following restrictions:
|
||||
//Use the PolyVox namespace
|
||||
using namespace PolyVox;
|
||||
|
||||
void createSphereInVolume(PagedVolume<uint8_t>& volData, float fRadius)
|
||||
void createSphereInVolume(RawVolume<uint8_t>& volData, float fRadius)
|
||||
{
|
||||
//This vector hold the position of the center of the volume
|
||||
Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2);
|
||||
@ -58,11 +57,11 @@ void createSphereInVolume(PagedVolume<uint8_t>& volData, float fRadius)
|
||||
uint8_t uDensity = std::numeric_limits<uint8_t>::max();
|
||||
|
||||
//Wrte the voxel value into the volume
|
||||
volData.setVoxelAt(x, y, z, uDensity);
|
||||
volData.setVoxel(x, y, z, uDensity);
|
||||
}
|
||||
|
||||
//144 in the middle, (144 - 32) at the edges. Threshold of 128 is between these
|
||||
//volData.setVoxelAt(x, y, z, 144 - fDistToCenter);
|
||||
//volData.setVoxel(x, y, z, 144 - fDistToCenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,7 +79,7 @@ protected:
|
||||
void initializeExample() override
|
||||
{
|
||||
//Create an empty volume and then place a sphere in it
|
||||
PagedVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
||||
RawVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
||||
createSphereInVolume(volData, 28);
|
||||
|
||||
//Smooth the data - should reimplement this using LowPassFilter
|
||||
@ -90,7 +89,7 @@ protected:
|
||||
|
||||
RawVolume<uint8_t> volDataLowLOD(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(15, 31, 31)));
|
||||
|
||||
VolumeResampler< PagedVolume<uint8_t>, RawVolume<uint8_t> > volumeResampler(&volData, PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(31, 63, 63)), &volDataLowLOD, volDataLowLOD.getEnclosingRegion());
|
||||
VolumeResampler< RawVolume<uint8_t>, RawVolume<uint8_t> > volumeResampler(&volData, PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(31, 63, 63)), &volDataLowLOD, volDataLowLOD.getEnclosingRegion());
|
||||
volumeResampler.execute();
|
||||
|
||||
//Extract the surface
|
||||
|
@ -33,7 +33,7 @@ freely, subject to the following restrictions:
|
||||
|
||||
//These two should not be here!
|
||||
#include "PolyVox/Material.h"
|
||||
#include "PolyVox/PagedVolume.h"
|
||||
#include "PolyVox/RawVolume.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -53,7 +53,7 @@ namespace PolyVox
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const PagedVolume<uint8_t>::Sampler& sampler)
|
||||
bool operator()(const RawVolume<uint8_t>::Sampler& sampler)
|
||||
{
|
||||
uint8_t sample = sampler.getVoxel();
|
||||
bool func = mIsVoxelTransparentCallback(sample);
|
||||
|
@ -98,7 +98,7 @@ namespace PolyVox
|
||||
return m_pElements[z * m_uDimensions[0] * m_uDimensions[1] + y * m_uDimensions[0] + x];
|
||||
}
|
||||
|
||||
uint32_t getDimension(uint32_t dimension)
|
||||
uint32_t getDimension(uint32_t dimension) const
|
||||
{
|
||||
return m_uDimensions[dimension];
|
||||
}
|
||||
|
@ -36,23 +36,6 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// More details to come...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace WrapModes
|
||||
{
|
||||
enum WrapMode
|
||||
{
|
||||
Validate = 0,
|
||||
Clamp = 1,
|
||||
Border = 2,
|
||||
AssumeValid = 3
|
||||
};
|
||||
}
|
||||
typedef WrapModes::WrapMode WrapMode;
|
||||
|
||||
// Required for a trick to implement specialization of template member
|
||||
// functions in template classes. See http://stackoverflow.com/a/4951057
|
||||
template <WrapMode W> struct WrapModeType{};
|
||||
|
||||
template <typename _VoxelType>
|
||||
class BaseVolume
|
||||
{
|
||||
@ -70,12 +53,9 @@ namespace PolyVox
|
||||
Vector3DInt32 getPosition(void) const;
|
||||
inline VoxelType getVoxel(void) const;
|
||||
|
||||
bool isCurrentPositionValid(void) const;
|
||||
|
||||
void setPosition(const Vector3DInt32& v3dNewPos);
|
||||
void setPosition(int32_t xPos, int32_t yPos, int32_t zPos);
|
||||
inline bool setVoxel(VoxelType tValue);
|
||||
void setWrapMode(WrapMode eWrapMode, VoxelType tBorder = VoxelType());
|
||||
|
||||
void movePositiveX(void);
|
||||
void movePositiveY(void);
|
||||
@ -116,7 +96,6 @@ namespace PolyVox
|
||||
inline VoxelType peekVoxel1px1py1pz(void) const;
|
||||
|
||||
protected:
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
|
||||
DerivedVolumeType* mVolume;
|
||||
|
||||
@ -124,70 +103,26 @@ namespace PolyVox
|
||||
int32_t mXPosInVolume;
|
||||
int32_t mYPosInVolume;
|
||||
int32_t mZPosInVolume;
|
||||
|
||||
WrapMode m_eWrapMode;
|
||||
VoxelType m_tBorder;
|
||||
|
||||
//Whether the current position is inside the volume
|
||||
//FIXME - Replace these with flags
|
||||
bool m_bIsCurrentPositionValidInX;
|
||||
bool m_bIsCurrentPositionValidInY;
|
||||
bool m_bIsCurrentPositionValidInZ;
|
||||
};
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// Gets the value used for voxels which are outside the volume
|
||||
VoxelType getBorderValue(void) const;
|
||||
/// Gets a Region representing the extents of the Volume.
|
||||
const Region& getEnclosingRegion(void) const;
|
||||
/// Gets the width of the volume in voxels.
|
||||
int32_t getWidth(void) const;
|
||||
/// Gets the height of the volume in voxels.
|
||||
int32_t getHeight(void) const;
|
||||
/// Gets the depth of the volume in voxels.
|
||||
int32_t getDepth(void) const;
|
||||
/// Gets the length of the longest side in voxels
|
||||
int32_t getLongestSideLength(void) const;
|
||||
/// Gets the length of the shortest side in voxels
|
||||
int32_t getShortestSideLength(void) const;
|
||||
/// Gets the length of the diagonal in voxels
|
||||
float getDiagonalLength(void) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const;
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
|
||||
/// Sets the value used for voxels which are outside the volume
|
||||
void setBorderValue(const VoxelType& tBorder);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue);
|
||||
|
||||
/// Calculates approximatly how many bytes of memory the volume is currently using.
|
||||
uint32_t calculateSizeInBytes(void);
|
||||
|
||||
protected:
|
||||
/// Constructor for creating a fixed size volume.
|
||||
BaseVolume(const Region& regValid);
|
||||
/// Constructor for creating a volume.
|
||||
BaseVolume();
|
||||
|
||||
/// Copy constructor
|
||||
BaseVolume(const BaseVolume& rhs);
|
||||
@ -197,17 +132,6 @@ namespace PolyVox
|
||||
|
||||
/// Assignment operator
|
||||
BaseVolume& operator=(const BaseVolume& rhs);
|
||||
|
||||
//The size of the volume
|
||||
Region m_regValidRegion;
|
||||
|
||||
//Some useful sizes
|
||||
int32_t m_uLongestSideLength;
|
||||
int32_t m_uShortestSideLength;
|
||||
float m_fDiagonalLength;
|
||||
|
||||
//The border value
|
||||
VoxelType m_tBorderValue;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -29,9 +29,7 @@ namespace PolyVox
|
||||
/// \sa RawVolume, PagedVolume
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
BaseVolume<VoxelType>::BaseVolume(const Region& regValid)
|
||||
:m_regValidRegion(regValid)
|
||||
,m_tBorderValue()
|
||||
BaseVolume<VoxelType>::BaseVolume()
|
||||
{
|
||||
}
|
||||
|
||||
@ -45,7 +43,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
BaseVolume<VoxelType>::BaseVolume(const BaseVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented to prevent accidental copying.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -66,127 +64,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
BaseVolume<VoxelType>& BaseVolume<VoxelType>::operator=(const BaseVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The border value is returned whenever an attempt is made to read a voxel which
|
||||
/// is outside the extents of the volume.
|
||||
/// \return The value used for voxels outside of the volume
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getBorderValue(void) const
|
||||
{
|
||||
return m_tBorderValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return A Region representing the extent of the volume.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
const Region& BaseVolume<VoxelType>::getEnclosingRegion(void) const
|
||||
{
|
||||
return m_regValidRegion;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The width of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the width is 64.
|
||||
/// \sa getHeight(), getDepth()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t BaseVolume<VoxelType>::getWidth(void) const
|
||||
{
|
||||
return m_regValidRegion.getUpperX() - m_regValidRegion.getLowerX() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The height of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the height is 64.
|
||||
/// \sa getWidth(), getDepth()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t BaseVolume<VoxelType>::getHeight(void) const
|
||||
{
|
||||
return m_regValidRegion.getUpperY() - m_regValidRegion.getLowerY() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The depth of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the depth is 64.
|
||||
/// \sa getWidth(), getHeight()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t BaseVolume<VoxelType>::getDepth(void) const
|
||||
{
|
||||
return m_regValidRegion.getUpperZ() - m_regValidRegion.getLowerZ() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The length of the shortest side in voxels. For example, if a volume has
|
||||
/// dimensions 256x512x1024 this function will return 256.
|
||||
/// \sa getLongestSideLength(), getDiagonalLength()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t BaseVolume<VoxelType>::getShortestSideLength(void) const
|
||||
{
|
||||
return m_uShortestSideLength;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The length of the longest side in voxels. For example, if a volume has
|
||||
/// dimensions 256x512x1024 this function will return 1024.
|
||||
/// \sa getShortestSideLength(), getDiagonalLength()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t BaseVolume<VoxelType>::getLongestSideLength(void) const
|
||||
{
|
||||
return m_uLongestSideLength;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The length of the diagonal in voxels. For example, if a volume has
|
||||
/// dimensions 256x512x1024 this function will return sqrt(256*256+512*512+1024*1024)
|
||||
/// = 1173.139. This value is computed on volume creation so retrieving it is fast.
|
||||
/// \sa getShortestSideLength(), getLongestSideLength()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
float BaseVolume<VoxelType>::getDiagonalLength(void) const
|
||||
{
|
||||
return m_fDiagonalLength;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tBorder*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& /*v3dPos*/, VoxelType /*tBorder*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented to prevent accidental copying.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -195,12 +73,10 @@ namespace PolyVox
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
@ -210,50 +86,15 @@ namespace PolyVox
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& /*v3dPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& /*v3dPos*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxelAt(const Vector3DInt32& /*v3dPos*/) const
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param tBorder The value to use for voxels outside the volume.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void BaseVolume<VoxelType>::setBorderValue(const VoxelType& tBorder)
|
||||
{
|
||||
m_tBorderValue = tBorder;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos the \c x position of the voxel
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
@ -261,7 +102,7 @@ namespace PolyVox
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void BaseVolume<VoxelType>::setVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/, WrapMode /*eWrapMode*/)
|
||||
void BaseVolume<VoxelType>::setVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
}
|
||||
@ -271,37 +112,11 @@ namespace PolyVox
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void BaseVolume<VoxelType>::setVoxel(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/, WrapMode /*eWrapMode*/)
|
||||
void BaseVolume<VoxelType>::setVoxel(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos the \c x position of the voxel
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
/// \param uZPos the \c z position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \return whether the requested position is inside the volume
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
bool BaseVolume<VoxelType>::setVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos the 3D position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \return whether the requested position is inside the volume
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
bool BaseVolume<VoxelType>::setVoxelAt(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Note: This function needs reviewing for accuracy...
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -32,11 +32,6 @@ namespace PolyVox
|
||||
,mXPosInVolume(0)
|
||||
,mYPosInVolume(0)
|
||||
,mZPosInVolume(0)
|
||||
,m_eWrapMode(WrapModes::Border)
|
||||
,m_tBorder()
|
||||
,m_bIsCurrentPositionValidInX(false)
|
||||
,m_bIsCurrentPositionValidInY(false)
|
||||
,m_bIsCurrentPositionValidInZ(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -57,14 +52,7 @@ namespace PolyVox
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getVoxel(void) const
|
||||
{
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume, WrapModes::Validate); // FIXME - Use templatised version instead but watch for Linux compile errors.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
bool inline BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::isCurrentPositionValid(void) const
|
||||
{
|
||||
return m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ;
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -81,25 +69,13 @@ namespace PolyVox
|
||||
mXPosInVolume = xPos;
|
||||
mYPosInVolume = yPos;
|
||||
mZPosInVolume = zPos;
|
||||
|
||||
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(xPos);
|
||||
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(yPos);
|
||||
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(zPos);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
bool BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::setVoxel(VoxelType tValue)
|
||||
{
|
||||
return mVolume->setVoxelAt(mXPosInVolume, mYPosInVolume, mZPosInVolume, tValue);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::setWrapMode(WrapMode eWrapMode, VoxelType tBorder)
|
||||
{
|
||||
m_eWrapMode = eWrapMode;
|
||||
m_tBorder = tBorder;
|
||||
return mVolume->setVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume, tValue);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -107,7 +83,6 @@ namespace PolyVox
|
||||
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::movePositiveX(void)
|
||||
{
|
||||
mXPosInVolume++;
|
||||
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(mXPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -115,7 +90,6 @@ namespace PolyVox
|
||||
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::movePositiveY(void)
|
||||
{
|
||||
mYPosInVolume++;
|
||||
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(mYPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -123,7 +97,6 @@ namespace PolyVox
|
||||
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::movePositiveZ(void)
|
||||
{
|
||||
mZPosInVolume++;
|
||||
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -131,7 +104,6 @@ namespace PolyVox
|
||||
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::moveNegativeX(void)
|
||||
{
|
||||
mXPosInVolume--;
|
||||
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(mXPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -139,7 +111,6 @@ namespace PolyVox
|
||||
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::moveNegativeY(void)
|
||||
{
|
||||
mYPosInVolume--;
|
||||
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(mYPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -147,70 +118,69 @@ namespace PolyVox
|
||||
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::moveNegativeZ(void)
|
||||
{
|
||||
mZPosInVolume--;
|
||||
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1ny1nz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
return mVolume->getVoxel(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1ny0pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume );
|
||||
return mVolume->getVoxel(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1ny1pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
return mVolume->getVoxel(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx0py1nz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume - 1);
|
||||
return mVolume->getVoxel(mXPosInVolume - 1, mYPosInVolume, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx0py0pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume );
|
||||
return mVolume->getVoxel(mXPosInVolume - 1, mYPosInVolume, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx0py1pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume + 1);
|
||||
return mVolume->getVoxel(mXPosInVolume - 1, mYPosInVolume, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1py1nz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
return mVolume->getVoxel(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1py0pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume );
|
||||
return mVolume->getVoxel(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1py1pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
return mVolume->getVoxel(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -219,63 +189,63 @@ namespace PolyVox
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1ny1nz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1ny0pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume );
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume - 1, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1ny1pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px0py1nz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume , mZPosInVolume - 1);
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px0py0pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume , mZPosInVolume );
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px0py1pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume , mZPosInVolume + 1);
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1py1nz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1py0pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume );
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume + 1, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1py1pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -284,83 +254,62 @@ namespace PolyVox
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1ny1nz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
return mVolume->getVoxel(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1ny0pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume );
|
||||
return mVolume->getVoxel(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1ny1pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
return mVolume->getVoxel(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px0py1nz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume - 1);
|
||||
return mVolume->getVoxel(mXPosInVolume + 1, mYPosInVolume, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px0py0pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume );
|
||||
return mVolume->getVoxel(mXPosInVolume + 1, mYPosInVolume, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px0py1pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume + 1);
|
||||
return mVolume->getVoxel(mXPosInVolume + 1, mYPosInVolume, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1py1nz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
return mVolume->getVoxel(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1py0pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume );
|
||||
return mVolume->getVoxel(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1py1pz(void) const
|
||||
{
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
switch(m_eWrapMode)
|
||||
{
|
||||
case WrapModes::Validate:
|
||||
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::Validate, m_tBorder);
|
||||
case WrapModes::Clamp:
|
||||
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::Clamp, m_tBorder);
|
||||
case WrapModes::Border:
|
||||
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::Border, m_tBorder);
|
||||
case WrapModes::AssumeValid:
|
||||
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::AssumeValid, m_tBorder);
|
||||
default:
|
||||
// Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid wrap mode");
|
||||
return VoxelType();
|
||||
}
|
||||
return mVolume->getVoxel(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ namespace PolyVox
|
||||
};
|
||||
|
||||
public:
|
||||
CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true);
|
||||
CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), bool bMergeQuads = true);
|
||||
|
||||
void execute();
|
||||
|
||||
@ -147,10 +147,6 @@ namespace PolyVox
|
||||
//This constant defines the maximum number of quads which can share a
|
||||
//vertex in a cubic style mesh. See the initialisation for more details.
|
||||
static const uint32_t MaxVerticesPerPosition;
|
||||
|
||||
//The wrap mode
|
||||
WrapMode m_eWrapMode;
|
||||
typename VolumeType::VoxelType m_tBorderValue;
|
||||
};
|
||||
|
||||
// This version of the function performs the extraction into a user-provided mesh rather than allocating a mesh automatically.
|
||||
@ -167,9 +163,9 @@ namespace PolyVox
|
||||
// are provided (would the third parameter be a controller or a mesh?). It seems this can be fixed by using enable_if/static_assert to emulate concepts,
|
||||
// but this is relatively complex and I haven't done it yet. Could always add it later as another overload.
|
||||
template<typename VolumeType, typename MeshType, typename IsQuadNeeded = DefaultIsQuadNeeded<typename VolumeType::VoxelType> >
|
||||
void extractCubicMeshCustom(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true)
|
||||
void extractCubicMeshCustom(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), bool bMergeQuads = true)
|
||||
{
|
||||
CubicSurfaceExtractor<VolumeType, MeshType, IsQuadNeeded> extractor(volData, region, result, isQuadNeeded, eWrapMode, tBorderValue, bMergeQuads);
|
||||
CubicSurfaceExtractor<VolumeType, MeshType, IsQuadNeeded> extractor(volData, region, result, isQuadNeeded, bMergeQuads);
|
||||
extractor.execute();
|
||||
}
|
||||
|
||||
@ -215,10 +211,10 @@ namespace PolyVox
|
||||
/// Another scenario which sometimes results in confusion is when you wish to extract a region which corresponds to the whole volume, partcularly when solid voxels extend right to the edge of the volume.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename VolumeType, typename IsQuadNeeded = DefaultIsQuadNeeded<typename VolumeType::VoxelType> >
|
||||
Mesh<CubicVertex<typename VolumeType::VoxelType> > extractCubicMesh(VolumeType* volData, Region region, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true)
|
||||
Mesh<CubicVertex<typename VolumeType::VoxelType> > extractCubicMesh(VolumeType* volData, Region region, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), bool bMergeQuads = true)
|
||||
{
|
||||
Mesh< CubicVertex<typename VolumeType::VoxelType> > result;
|
||||
extractCubicMeshCustom(volData, region, &result, isQuadNeeded, eWrapMode, tBorderValue, bMergeQuads);
|
||||
extractCubicMeshCustom(volData, region, &result, isQuadNeeded, bMergeQuads);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -36,15 +36,13 @@ namespace PolyVox
|
||||
const uint32_t CubicSurfaceExtractor<VolumeType, MeshType, IsQuadNeeded>::MaxVerticesPerPosition = 8;
|
||||
|
||||
template<typename VolumeType, typename MeshType, typename IsQuadNeeded>
|
||||
CubicSurfaceExtractor<VolumeType, MeshType, IsQuadNeeded>::CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads)
|
||||
CubicSurfaceExtractor<VolumeType, MeshType, IsQuadNeeded>::CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded, bool bMergeQuads)
|
||||
:m_volData(volData)
|
||||
,m_regSizeInVoxels(region)
|
||||
,m_meshCurrent(result)
|
||||
,m_previousSliceVertices(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2, m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2, MaxVerticesPerPosition)
|
||||
,m_currentSliceVertices(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2, m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2, MaxVerticesPerPosition)
|
||||
,m_bMergeQuads(bMergeQuads)
|
||||
,m_eWrapMode(eWrapMode)
|
||||
,m_tBorderValue(tBorderValue)
|
||||
{
|
||||
m_funcIsQuadNeededCallback = isQuadNeeded;
|
||||
|
||||
@ -80,7 +78,6 @@ namespace PolyVox
|
||||
m_vecQuads[PositiveZ].resize(m_regSizeInVoxels.getUpperZ() - m_regSizeInVoxels.getLowerZ() + 2);
|
||||
|
||||
typename VolumeType::Sampler volumeSampler(m_volData);
|
||||
volumeSampler.setWrapMode(m_eWrapMode, m_tBorderValue);
|
||||
|
||||
for(int32_t z = m_regSizeInVoxels.getLowerZ(); z <= m_regSizeInVoxels.getUpperZ(); z++)
|
||||
{
|
||||
|
@ -117,6 +117,11 @@ namespace PolyVox
|
||||
else
|
||||
{
|
||||
POLYVOX_LOG_TRACE("No data found for " << region << " during paging in.");
|
||||
|
||||
// Just fill with zeros. This feels hacky... perhaps we should just throw
|
||||
// an exception and let the calling code handle it and fill with zeros.
|
||||
uint32_t noOfVoxels = region.getWidthInVoxels() * region.getHeightInVoxels() * region.getDepthInVoxels();
|
||||
std::fill(pChunk->getData(), pChunk->getData() + noOfVoxels, VoxelType());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,13 +25,13 @@ freely, subject to the following restrictions:
|
||||
#define __PolyVox_Config_H__
|
||||
|
||||
//#define POLYVOX_LOG_TRACE_ENABLED
|
||||
#define POLYVOX_LOG_DEBUG_ENABLED
|
||||
//#define POLYVOX_LOG_DEBUG_ENABLED
|
||||
#define POLYVOX_LOG_INFO_ENABLED
|
||||
#define POLYVOX_LOG_WARNING_ENABLED
|
||||
#define POLYVOX_LOG_ERROR_ENABLED
|
||||
#define POLYVOX_LOG_FATAL_ENABLED
|
||||
|
||||
#define POLYVOX_ASSERTS_ENABLED
|
||||
//#define POLYVOX_ASSERTS_ENABLED
|
||||
#define POLYVOX_THROW_ENABLED
|
||||
|
||||
#endif
|
||||
|
@ -52,13 +52,13 @@ namespace PolyVox
|
||||
return elapsed_seconds.count();
|
||||
}
|
||||
|
||||
uint32_t elapsedTimeInMilliSeconds(void)
|
||||
float elapsedTimeInMilliSeconds(void)
|
||||
{
|
||||
std::chrono::duration<float, std::milli> elapsed_milliseconds = clock::now() - m_start;
|
||||
return elapsed_milliseconds.count();
|
||||
}
|
||||
|
||||
uint32_t elapsedTimeInMicroSeconds(void)
|
||||
float elapsedTimeInMicroSeconds(void)
|
||||
{
|
||||
std::chrono::duration<float, std::micro> elapsed_microseconds = clock::now() - m_start;
|
||||
return elapsed_microseconds.count();
|
||||
|
@ -114,7 +114,7 @@ namespace PolyVox
|
||||
tSrcVoxel /= 27;
|
||||
|
||||
//tSrcVoxel.setDensity(uDensity);
|
||||
m_pVolDst->setVoxelAt(iSrcX, iSrcY, iSrcZ, static_cast<typename DstVolumeType::VoxelType>(tSrcVoxel));
|
||||
m_pVolDst->setVoxel(iSrcX, iSrcY, iSrcZ, static_cast<typename DstVolumeType::VoxelType>(tSrcVoxel));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -141,7 +141,7 @@ namespace PolyVox
|
||||
{
|
||||
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
|
||||
{
|
||||
satVolume.setVoxelAt(x,y,z,0);
|
||||
satVolume.setVoxel(x,y,z,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -178,10 +178,10 @@ namespace PolyVox
|
||||
{
|
||||
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
|
||||
{
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x-1,y,z));
|
||||
AccumulationType currentVal = static_cast<AccumulationType>(m_pVolSrc->getVoxelAt(x,y,z));
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x-1,y,z));
|
||||
AccumulationType currentVal = static_cast<AccumulationType>(m_pVolSrc->getVoxel(x,y,z));
|
||||
|
||||
satVolume.setVoxelAt(x,y,z,previousSum + currentVal);
|
||||
satVolume.setVoxel(x,y,z,previousSum + currentVal);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
@ -192,10 +192,10 @@ namespace PolyVox
|
||||
{
|
||||
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
|
||||
{
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y-1,z, WrapModes::Border));
|
||||
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z, WrapModes::Border));
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y-1,z));
|
||||
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z));
|
||||
|
||||
satVolume.setVoxelAt(x,y,z,previousSum + currentSum);
|
||||
satVolume.setVoxel(x,y,z,previousSum + currentSum);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,10 +206,10 @@ namespace PolyVox
|
||||
{
|
||||
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
|
||||
{
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z-1, WrapModes::Border));
|
||||
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z, WrapModes::Border));
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z-1));
|
||||
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z));
|
||||
|
||||
satVolume.setVoxelAt(x,y,z,previousSum + currentSum);
|
||||
satVolume.setVoxel(x,y,z,previousSum + currentSum);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -234,20 +234,20 @@ namespace PolyVox
|
||||
int32_t satUpperY = iSrcY + border;
|
||||
int32_t satUpperZ = iSrcZ + border;
|
||||
|
||||
AccumulationType a = satVolume.getVoxel(satLowerX,satLowerY,satLowerZ, WrapModes::Border);
|
||||
AccumulationType b = satVolume.getVoxel(satUpperX,satLowerY,satLowerZ, WrapModes::Border);
|
||||
AccumulationType c = satVolume.getVoxel(satLowerX,satUpperY,satLowerZ, WrapModes::Border);
|
||||
AccumulationType d = satVolume.getVoxel(satUpperX,satUpperY,satLowerZ, WrapModes::Border);
|
||||
AccumulationType e = satVolume.getVoxel(satLowerX,satLowerY,satUpperZ, WrapModes::Border);
|
||||
AccumulationType f = satVolume.getVoxel(satUpperX,satLowerY,satUpperZ, WrapModes::Border);
|
||||
AccumulationType g = satVolume.getVoxel(satLowerX,satUpperY,satUpperZ, WrapModes::Border);
|
||||
AccumulationType h = satVolume.getVoxel(satUpperX,satUpperY,satUpperZ, WrapModes::Border);
|
||||
AccumulationType a = satVolume.getVoxel(satLowerX,satLowerY,satLowerZ);
|
||||
AccumulationType b = satVolume.getVoxel(satUpperX,satLowerY,satLowerZ);
|
||||
AccumulationType c = satVolume.getVoxel(satLowerX,satUpperY,satLowerZ);
|
||||
AccumulationType d = satVolume.getVoxel(satUpperX,satUpperY,satLowerZ);
|
||||
AccumulationType e = satVolume.getVoxel(satLowerX,satLowerY,satUpperZ);
|
||||
AccumulationType f = satVolume.getVoxel(satUpperX,satLowerY,satUpperZ);
|
||||
AccumulationType g = satVolume.getVoxel(satLowerX,satUpperY,satUpperZ);
|
||||
AccumulationType h = satVolume.getVoxel(satUpperX,satUpperY,satUpperZ);
|
||||
|
||||
AccumulationType sum = h+c-d-g-f-a+b+e;
|
||||
uint32_t sideLength = border * 2 + 1;
|
||||
AccumulationType average = sum / (sideLength*sideLength*sideLength);
|
||||
|
||||
m_pVolDst->setVoxelAt(iDstX, iDstY, iDstZ, static_cast<typename DstVolumeType::VoxelType>(average));
|
||||
m_pVolDst->setVoxel(iDstX, iDstY, iDstZ, static_cast<typename DstVolumeType::VoxelType>(average));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ namespace PolyVox
|
||||
class MarchingCubesSurfaceExtractor
|
||||
{
|
||||
public:
|
||||
MarchingCubesSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, ControllerType controller, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType());
|
||||
MarchingCubesSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, ControllerType controller);
|
||||
|
||||
void execute();
|
||||
|
||||
@ -338,17 +338,17 @@ namespace PolyVox
|
||||
// are provided (would the third parameter be a controller or a mesh?). It seems this can be fixed by using enable_if/static_assert to emulate concepts,
|
||||
// but this is relatively complex and I haven't done it yet. Could always add it later as another overload.
|
||||
template< typename VolumeType, typename MeshType, typename ControllerType = DefaultMarchingCubesController<typename VolumeType::VoxelType> >
|
||||
void extractMarchingCubesMeshCustom(VolumeType* volData, Region region, MeshType* result, ControllerType controller = ControllerType(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType())
|
||||
void extractMarchingCubesMeshCustom(VolumeType* volData, Region region, MeshType* result, ControllerType controller = ControllerType())
|
||||
{
|
||||
MarchingCubesSurfaceExtractor<VolumeType, MeshType, ControllerType> extractor(volData, region, result, controller, eWrapMode, tBorderValue);
|
||||
MarchingCubesSurfaceExtractor<VolumeType, MeshType, ControllerType> extractor(volData, region, result, controller);
|
||||
extractor.execute();
|
||||
}
|
||||
|
||||
template< typename VolumeType, typename ControllerType = DefaultMarchingCubesController<typename VolumeType::VoxelType> >
|
||||
Mesh<MarchingCubesVertex<typename VolumeType::VoxelType> > extractMarchingCubesMesh(VolumeType* volData, Region region, ControllerType controller = ControllerType(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType())
|
||||
Mesh<MarchingCubesVertex<typename VolumeType::VoxelType> > extractMarchingCubesMesh(VolumeType* volData, Region region, ControllerType controller = ControllerType())
|
||||
{
|
||||
Mesh<MarchingCubesVertex<typename VolumeType::VoxelType> > result;
|
||||
extractMarchingCubesMeshCustom<VolumeType, Mesh<MarchingCubesVertex<typename VolumeType::VoxelType>, DefaultIndexType > >(volData, region, &result, controller, eWrapMode, tBorderValue);
|
||||
extractMarchingCubesMeshCustom<VolumeType, Mesh<MarchingCubesVertex<typename VolumeType::VoxelType>, DefaultIndexType > >(volData, region, &result, controller);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ freely, subject to the following restrictions:
|
||||
namespace PolyVox
|
||||
{
|
||||
template<typename VolumeType, typename MeshType, typename ControllerType>
|
||||
MarchingCubesSurfaceExtractor<VolumeType, MeshType, ControllerType>::MarchingCubesSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, ControllerType controller, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue)
|
||||
MarchingCubesSurfaceExtractor<VolumeType, MeshType, ControllerType>::MarchingCubesSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, ControllerType controller)
|
||||
:m_volData(volData)
|
||||
,m_sampVolume(volData)
|
||||
,m_meshCurrent(result)
|
||||
@ -38,8 +38,6 @@ namespace PolyVox
|
||||
//m_regSizeInVoxels.cropTo(m_volData->getEnclosingRegion());
|
||||
m_regSizeInCells = m_regSizeInVoxels;
|
||||
m_regSizeInCells.setUpperCorner(m_regSizeInCells.getUpperCorner() - Vector3DInt32(1,1,1));
|
||||
|
||||
m_sampVolume.setWrapMode(eWrapMode, tBorderValue);
|
||||
}
|
||||
|
||||
template<typename VolumeType, typename MeshType, typename ControllerType>
|
||||
|
@ -130,8 +130,8 @@ namespace PolyVox
|
||||
VoxelType getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const;
|
||||
VoxelType getVoxel(const Vector3DUint16& v3dPos) const;
|
||||
|
||||
void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
|
||||
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
|
||||
void setVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
|
||||
void setVoxel(const Vector3DUint16& v3dPos, VoxelType tValue);
|
||||
|
||||
private:
|
||||
/// Private copy constructor to prevent accisdental copying
|
||||
@ -249,42 +249,20 @@ namespace PolyVox
|
||||
|
||||
public:
|
||||
/// Constructor for creating a fixed size volume.
|
||||
PagedVolume
|
||||
(
|
||||
const Region& regValid,
|
||||
Pager* pPager = nullptr,
|
||||
uint16_t uChunkSideLength = 32
|
||||
);
|
||||
PagedVolume(Pager* pPager, uint32_t uTargetMemoryUsageInBytes = 256 * 1024 * 1024, uint16_t uChunkSideLength = 32);
|
||||
/// Destructor
|
||||
~PagedVolume();
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const;
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
|
||||
/// Sets the number of chunks for which uncompressed data is stored
|
||||
void setMemoryUsageLimit(uint32_t uMemoryUsageInBytes);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue);
|
||||
|
||||
/// Tries to ensure that the voxels within the specified Region are loaded into memory.
|
||||
void prefetch(Region regPrefetch);
|
||||
/// Ensures that any voxels within the specified Region are removed from memory.
|
||||
@ -303,18 +281,6 @@ namespace PolyVox
|
||||
PagedVolume& operator=(const PagedVolume& rhs);
|
||||
|
||||
private:
|
||||
|
||||
// FIXME - We can probably ove this into the constructor
|
||||
void initialise();
|
||||
|
||||
// A trick to implement specialization of template member functions in template classes. See http://stackoverflow.com/a/4951057
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const;
|
||||
|
||||
std::shared_ptr<Chunk> getChunk(int32_t uChunkX, int32_t uChunkY, int32_t uChunkZ) const;
|
||||
|
||||
void purgeNullPtrsFromAllChunks(void) const;
|
||||
@ -338,24 +304,20 @@ namespace PolyVox
|
||||
typedef std::unordered_map<Vector3DInt32, std::shared_ptr< Chunk > > SharedPtrChunkMap;
|
||||
mutable SharedPtrChunkMap m_pRecentlyUsedChunks;
|
||||
|
||||
mutable uint32_t m_uTimestamper;
|
||||
mutable Vector3DInt32 m_v3dLastAccessedChunkPos;
|
||||
mutable std::shared_ptr<Chunk> m_pLastAccessedChunk;
|
||||
uint32_t m_uChunkCountLimit;
|
||||
mutable uint32_t m_uTimestamper = 0;
|
||||
mutable Vector3DInt32 m_v3dLastAccessedChunkPos = Vector3DInt32(0, 0, 0); //There are no invalid positions, but initially the m_pLastAccessedChunk pointer will be null
|
||||
mutable std::shared_ptr<Chunk> m_pLastAccessedChunk = nullptr;
|
||||
uint32_t m_uChunkCountLimit = 0;
|
||||
|
||||
// The size of the volume
|
||||
Region m_regValidRegionInChunks;
|
||||
//Region m_regValidRegionInChunks;
|
||||
|
||||
// The size of the chunks
|
||||
uint16_t m_uChunkSideLength;
|
||||
uint8_t m_uChunkSideLengthPower;
|
||||
int32_t m_iChunkMask;
|
||||
|
||||
Pager* m_pPager;
|
||||
|
||||
// Enough to make sure a chunks and it's neighbours can be loaded, with a few to spare.
|
||||
const uint32_t uMinPracticalNoOfChunks = 32;
|
||||
// Should prevent multi-gigabyte volumes when chunk sizes are reasonable.
|
||||
const uint32_t uMaxPracticalNoOfChunks = 32768;
|
||||
Pager* m_pPager = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,62 +30,43 @@ 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 PagedVolume constructor).
|
||||
/// \param regValid Specifies the minimum and maximum valid voxel positions.
|
||||
/// \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 PagedVolume.
|
||||
/// \param pPager Called by PolyVox to load and unload data on demand.
|
||||
/// \param uTargetMemoryUsageInBytes The upper limit to how much memory this PagedVolume should aim to use.
|
||||
/// \param uChunkSideLength The size of the chunks making up the volume. Small chunks will compress/decompress faster, but there will also be more of them meaning voxel access could be slower.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
PagedVolume<VoxelType>::PagedVolume
|
||||
(
|
||||
const Region& regValid,
|
||||
Pager* pPager,
|
||||
uint16_t uChunkSideLength
|
||||
)
|
||||
:BaseVolume<VoxelType>(regValid)
|
||||
PagedVolume<VoxelType>::PagedVolume(Pager* pPager, uint32_t uTargetMemoryUsageInBytes, uint16_t uChunkSideLength)
|
||||
:BaseVolume<VoxelType>()
|
||||
, m_pPager(pPager)
|
||||
, m_uChunkSideLength(uChunkSideLength)
|
||||
{
|
||||
m_uChunkSideLength = uChunkSideLength;
|
||||
m_pPager = pPager;
|
||||
// Validation of parameters
|
||||
POLYVOX_THROW_IF(!pPager, std::invalid_argument, "You must provide a valid pager when constructing a PagedVolume");
|
||||
POLYVOX_THROW_IF(uTargetMemoryUsageInBytes < 1 * 1024 * 1024, std::invalid_argument, "Target memory usage is too small to be practical");
|
||||
POLYVOX_THROW_IF(m_uChunkSideLength == 0, std::invalid_argument, "Chunk side length cannot be zero.");
|
||||
POLYVOX_THROW_IF(m_uChunkSideLength > 256, std::invalid_argument, "Chunk size is too large to be practical.");
|
||||
POLYVOX_THROW_IF(!isPowerOf2(m_uChunkSideLength), std::invalid_argument, "Chunk side length must be a power of two.");
|
||||
|
||||
if (m_pPager)
|
||||
{
|
||||
// If the user is creating a vast (almost infinite) volume then we can bet they will be
|
||||
// expecting a high memory usage and will want a fair number of chunks to play around with.
|
||||
if (regValid == Region::MaxRegion())
|
||||
{
|
||||
m_uChunkCountLimit = 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise we try to choose a chunk count to avoid too much thrashing, particularly when iterating
|
||||
// over the whole volume. This means at least enough chunks to cover one edge of the volume, and ideally
|
||||
// enough for a whole face. Which face? Longest edge by shortest edge seems like a reasonable guess.
|
||||
uint32_t longestSide = (std::max)(regValid.getWidthInVoxels(), (std::max)(regValid.getHeightInVoxels(), regValid.getDepthInVoxels()));
|
||||
uint32_t shortestSide = (std::min)(regValid.getWidthInVoxels(), (std::min)(regValid.getHeightInVoxels(), regValid.getDepthInVoxels()));
|
||||
// Used to perform multiplications and divisions by bit shifting.
|
||||
m_uChunkSideLengthPower = logBase2(m_uChunkSideLength);
|
||||
// Use to perform modulo by bit operations
|
||||
m_iChunkMask = m_uChunkSideLength - 1;
|
||||
|
||||
longestSide /= m_uChunkSideLength;
|
||||
shortestSide /= m_uChunkSideLength;
|
||||
// Calculate the number of chunks based on the memory limit and the size of each chunk.
|
||||
uint32_t uChunkSizeInBytes = PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(m_uChunkSideLength);
|
||||
m_uChunkCountLimit = uTargetMemoryUsageInBytes / uChunkSizeInBytes;
|
||||
|
||||
m_uChunkCountLimit = longestSide * shortestSide;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there is no pager provided then we set the chunk limit to the maximum
|
||||
// value to ensure the system never attempts to page chunks out of memory.
|
||||
m_uChunkCountLimit = (std::numeric_limits<uint32_t>::max)();
|
||||
}
|
||||
|
||||
// Make sure the calculated chunk limit is within practical bounds
|
||||
// Enforce sensible limits on the number of chunks.
|
||||
const uint32_t uMinPracticalNoOfChunks = 32; // Enough to make sure a chunks and it's neighbours can be loaded, with a few to spare.
|
||||
const uint32_t uMaxPracticalNoOfChunks = 32768; // Should prevent multi-gigabyte volumes when chunk sizes are reasonable.
|
||||
POLYVOX_LOG_WARNING_IF(m_uChunkCountLimit < uMinPracticalNoOfChunks, "Requested memory usage limit of "
|
||||
<< uTargetMemoryUsageInBytes / (1024 * 1024) << "Mb is too low and cannot be adhered to.");
|
||||
m_uChunkCountLimit = (std::max)(m_uChunkCountLimit, uMinPracticalNoOfChunks);
|
||||
m_uChunkCountLimit = (std::min)(m_uChunkCountLimit, uMaxPracticalNoOfChunks);
|
||||
|
||||
uint32_t uChunkSizeInBytes = PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(m_uChunkSideLength);
|
||||
POLYVOX_LOG_DEBUG("Memory usage limit for volume initially set to " << (m_uChunkCountLimit * uChunkSizeInBytes) / (1024 * 1024)
|
||||
// Inform the user about the chosen memory configuration.
|
||||
POLYVOX_LOG_DEBUG("Memory usage limit for volume now set to " << (m_uChunkCountLimit * uChunkSizeInBytes) / (1024 * 1024)
|
||||
<< "Mb (" << m_uChunkCountLimit << " chunks of " << uChunkSizeInBytes / 1024 << "Kb each).");
|
||||
|
||||
initialise();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -98,7 +79,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
PagedVolume<VoxelType>::PagedVolume(const PagedVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented to prevent accidental copying.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -120,43 +101,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
PagedVolume<VoxelType>& PagedVolume<VoxelType>::operator=(const PagedVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
|
||||
{
|
||||
// Simply call through to the real implementation
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<eWrapMode>(), tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const
|
||||
{
|
||||
// Simply call through to the real implementation
|
||||
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
|
||||
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented to prevent accidental copying.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -165,139 +110,43 @@ namespace PolyVox
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
switch(eWrapMode)
|
||||
{
|
||||
case WrapModes::Validate:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Validate>(), tBorder);
|
||||
case WrapModes::Clamp:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Clamp>(), tBorder);
|
||||
case WrapModes::Border:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Border>(), tBorder);
|
||||
case WrapModes::AssumeValid:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder);
|
||||
default:
|
||||
// Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid wrap mode");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)))
|
||||
VoxelType PagedVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
const int32_t chunkX = uXPos >> m_uChunkSideLengthPower;
|
||||
const int32_t chunkY = uYPos >> m_uChunkSideLengthPower;
|
||||
const int32_t chunkZ = uZPos >> m_uChunkSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (chunkX << m_uChunkSideLengthPower));
|
||||
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (chunkY << m_uChunkSideLengthPower));
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (chunkZ << m_uChunkSideLengthPower));
|
||||
const uint16_t xOffset = static_cast<uint16_t>(uXPos & m_iChunkMask);
|
||||
const uint16_t yOffset = static_cast<uint16_t>(uYPos & m_iChunkMask);
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos & m_iChunkMask);
|
||||
|
||||
auto pChunk = getChunk(chunkX, chunkY, chunkZ);
|
||||
|
||||
return pChunk->getVoxel(xOffset, yOffset, zOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->getBorderValue();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxelAt(const Vector3DInt32& v3dPos) const
|
||||
VoxelType PagedVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos) const
|
||||
{
|
||||
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Increasing the size of the chunk cache will increase memory but may improve performance.
|
||||
/// You may want to set this to a large value (e.g. 1024) when you are first loading your
|
||||
/// volume data and then set it to a smaller value (e.g.64) for general processing.
|
||||
/// \param uMaxNumberOfChunks The number of chunks for which uncompressed data can be cached.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::setMemoryUsageLimit(uint32_t uMemoryUsageInBytes)
|
||||
{
|
||||
POLYVOX_THROW_IF(!m_pPager, invalid_operation, "You cannot limit the memory usage of the volume because it was created without a pager attached.");
|
||||
|
||||
// Calculate the number of chunks based on the memory limit and the size of each chunk.
|
||||
uint32_t uChunkSizeInBytes = PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(m_uChunkSideLength);
|
||||
m_uChunkCountLimit = uMemoryUsageInBytes / uChunkSizeInBytes;
|
||||
|
||||
// We need at least a few chunks available to avoid thrashing, and in pratice there will probably be hundreds.
|
||||
POLYVOX_LOG_WARNING_IF(m_uChunkCountLimit < uMinPracticalNoOfChunks, "Requested memory usage limit of "
|
||||
<< uMemoryUsageInBytes / (1024 * 1024) << "Mb is too low and cannot be adhered to.");
|
||||
m_uChunkCountLimit = (std::max)(m_uChunkCountLimit, uMinPracticalNoOfChunks);
|
||||
m_uChunkCountLimit = (std::min)(m_uChunkCountLimit, uMaxPracticalNoOfChunks);
|
||||
|
||||
// If the new limit is less than the number of chunks already loaded then the easiest solution is to flush and start loading again.
|
||||
if (m_pRecentlyUsedChunks.size() > m_uChunkCountLimit)
|
||||
{
|
||||
flushAll();
|
||||
}
|
||||
|
||||
POLYVOX_LOG_DEBUG("Memory usage limit for volume now set to " << (m_uChunkCountLimit * uChunkSizeInBytes) / (1024 * 1024)
|
||||
<< "Mb (" << m_uChunkCountLimit << " chunks of " << uChunkSizeInBytes / 1024 << "Kb each).");
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos the \c x position of the voxel
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
/// \param uZPos the \c z position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
void PagedVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
||||
{
|
||||
if((eWrapMode != WrapModes::Validate) && (eWrapMode != WrapModes::AssumeValid))
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Invalid wrap mode in call to setVoxel(). It must be 'None' or 'DontCheck'.");
|
||||
}
|
||||
|
||||
// This validation is skipped if the wrap mode is 'DontCheck'
|
||||
if(eWrapMode == WrapModes::Validate)
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
|
||||
}
|
||||
}
|
||||
|
||||
const int32_t chunkX = uXPos >> m_uChunkSideLengthPower;
|
||||
const int32_t chunkY = uYPos >> m_uChunkSideLengthPower;
|
||||
const int32_t chunkZ = uZPos >> m_uChunkSideLengthPower;
|
||||
@ -307,62 +156,19 @@ namespace PolyVox
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (chunkZ << m_uChunkSideLengthPower));
|
||||
|
||||
auto pChunk = getChunk(chunkX, chunkY, chunkZ);
|
||||
pChunk->setVoxelAt(xOffset, yOffset, zOffset, tValue);
|
||||
pChunk->setVoxel(xOffset, yOffset, zOffset, tValue);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos the 3D position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
void PagedVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue)
|
||||
{
|
||||
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eWrapMode);
|
||||
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos the \c x position of the voxel
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
/// \param uZPos the \c z position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \return whether the requested position is inside the volume
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
bool PagedVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
|
||||
const int32_t chunkX = uXPos >> m_uChunkSideLengthPower;
|
||||
const int32_t chunkY = uYPos >> m_uChunkSideLengthPower;
|
||||
const int32_t chunkZ = uZPos >> m_uChunkSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (chunkX << m_uChunkSideLengthPower));
|
||||
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (chunkY << m_uChunkSideLengthPower));
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (chunkZ << m_uChunkSideLengthPower));
|
||||
|
||||
auto pChunk = getChunk(chunkX, chunkY, chunkZ);
|
||||
|
||||
pChunk->setVoxelAt(xOffset, yOffset, zOffset, tValue);
|
||||
|
||||
//Return true to indicate that we modified a voxel.
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos the 3D position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \return whether the requested position is inside the volume
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
bool PagedVolume<VoxelType>::setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue)
|
||||
{
|
||||
return setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Note that if the memory usage limit is not large enough to support the region this function will only load part of the region. In this case it is undefined which parts will actually be loaded. If all the voxels in the given region are already loaded, this function will not do anything. Other voxels might be unloaded to make space for the new voxels.
|
||||
/// \param regPrefetch The Region of voxels to prefetch into memory.
|
||||
@ -386,7 +192,7 @@ namespace PolyVox
|
||||
// Ensure we don't page in more chunks than the volume can hold.
|
||||
Region region(v3dStart, v3dEnd);
|
||||
uint32_t uNoOfChunks = static_cast<uint32_t>(region.getWidthInVoxels() * region.getHeightInVoxels() * region.getDepthInVoxels());
|
||||
POLYVOX_LOG_WARNING_IF(uNoOfChunks > m_uChunkCountLimit, "Attempting to prefetch more than the maximum number of chunks.");
|
||||
POLYVOX_LOG_WARNING_IF(uNoOfChunks > m_uChunkCountLimit, "Attempting to prefetch more than the maximum number of chunks (this will cause thrashing).");
|
||||
uNoOfChunks = (std::min)(uNoOfChunks, m_uChunkCountLimit);
|
||||
|
||||
// Loops over the specified positions and touch the corresponding chunks.
|
||||
@ -408,8 +214,6 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::flushAll()
|
||||
{
|
||||
POLYVOX_LOG_WARNING_IF(!m_pPager, "Data discarded by flush operation as no pager is attached.");
|
||||
|
||||
// Clear this pointer so it doesn't hang on to any chunks.
|
||||
m_pLastAccessedChunk = nullptr;
|
||||
|
||||
@ -429,8 +233,6 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::flush(Region regFlush)
|
||||
{
|
||||
POLYVOX_LOG_WARNING_IF(!m_pPager, "Data discarded by flush operation as no pager is attached.");
|
||||
|
||||
// Clear this pointer so it doesn't hang on to any chunks.
|
||||
m_pLastAccessedChunk = nullptr;
|
||||
|
||||
@ -465,48 +267,6 @@ namespace PolyVox
|
||||
purgeNullPtrsFromAllChunks();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This function should probably be made internal...
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::initialise()
|
||||
{
|
||||
//Validate parameters
|
||||
if(m_uChunkSideLength == 0)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Chunk side length cannot be zero.");
|
||||
}
|
||||
|
||||
if(!isPowerOf2(m_uChunkSideLength))
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Chunk side length must be a power of two.");
|
||||
}
|
||||
|
||||
m_uTimestamper = 0;
|
||||
m_v3dLastAccessedChunkPos = Vector3DInt32(0,0,0); //There are no invalid positions, but initially the m_pLastAccessedChunk pointer will be null;
|
||||
m_pLastAccessedChunk = nullptr;
|
||||
|
||||
//Compute the chunk side length
|
||||
m_uChunkSideLengthPower = logBase2(m_uChunkSideLength);
|
||||
|
||||
m_regValidRegionInChunks.setLowerX(this->m_regValidRegion.getLowerX() >> m_uChunkSideLengthPower);
|
||||
m_regValidRegionInChunks.setLowerY(this->m_regValidRegion.getLowerY() >> m_uChunkSideLengthPower);
|
||||
m_regValidRegionInChunks.setLowerZ(this->m_regValidRegion.getLowerZ() >> m_uChunkSideLengthPower);
|
||||
m_regValidRegionInChunks.setUpperX(this->m_regValidRegion.getUpperX() >> m_uChunkSideLengthPower);
|
||||
m_regValidRegionInChunks.setUpperY(this->m_regValidRegion.getUpperY() >> m_uChunkSideLengthPower);
|
||||
m_regValidRegionInChunks.setUpperZ(this->m_regValidRegion.getUpperZ() >> m_uChunkSideLengthPower);
|
||||
|
||||
//setMaxNumberOfChunks(m_uChunkCountLimit);
|
||||
|
||||
//Clear the previous data
|
||||
m_pRecentlyUsedChunks.clear();
|
||||
|
||||
//Other properties we might find useful later
|
||||
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<float>(this->getWidth() * this->getWidth() + this->getHeight() * this->getHeight() + this->getDepth() * this->getDepth()));
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
std::shared_ptr<typename PagedVolume<VoxelType>::Chunk> PagedVolume<VoxelType>::getChunk(int32_t uChunkX, int32_t uChunkY, int32_t uChunkZ) const
|
||||
{
|
||||
@ -566,10 +326,6 @@ namespace PolyVox
|
||||
bool erasedChunk = false;
|
||||
while (m_pRecentlyUsedChunks.size() + 1 > m_uChunkCountLimit) // +1 ready for new chunk we will add next.
|
||||
{
|
||||
// This should never hit, because it should not have been possible for
|
||||
// the user to limit the number of chunks if they did not provide a pager.
|
||||
POLYVOX_ASSERT(m_pPager, "A valid pager is required to limit number of chunks");
|
||||
|
||||
// Find the least recently used chunk. Hopefully this isn't too slow.
|
||||
typename SharedPtrChunkMap::iterator itUnloadChunk = m_pRecentlyUsedChunks.begin();
|
||||
for (typename SharedPtrChunkMap::iterator i = m_pRecentlyUsedChunks.begin(); i != m_pRecentlyUsedChunks.end(); i++)
|
||||
@ -633,66 +389,5 @@ namespace PolyVox
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const
|
||||
{
|
||||
// This function should never be called because one of the specialisations should always match.
|
||||
POLYVOX_ASSERT(false, "This function is not implemented and should never be called!");
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
|
||||
}
|
||||
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const
|
||||
{
|
||||
//Perform clamping
|
||||
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
|
||||
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
|
||||
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
|
||||
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
|
||||
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
|
||||
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
|
||||
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
{
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
else
|
||||
{
|
||||
return tBorder;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) const
|
||||
{
|
||||
const int32_t chunkX = uXPos >> m_uChunkSideLengthPower;
|
||||
const int32_t chunkY = uYPos >> m_uChunkSideLengthPower;
|
||||
const int32_t chunkZ = uZPos >> m_uChunkSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (chunkX << m_uChunkSideLengthPower));
|
||||
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (chunkY << m_uChunkSideLengthPower));
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (chunkZ << m_uChunkSideLengthPower));
|
||||
|
||||
auto pChunk = getChunk(chunkX, chunkY, chunkZ);
|
||||
return pChunk->getVoxel(xOffset, yOffset, zOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,8 @@ namespace PolyVox
|
||||
,m_pPager(pPager)
|
||||
,m_v3dChunkSpacePosition(v3dPosition)
|
||||
{
|
||||
POLYVOX_ASSERT(m_pPager, "No valid pager supplied to chunk constructor.");
|
||||
|
||||
// Compute the side length
|
||||
m_uSideLength = uSideLength;
|
||||
m_uSideLengthPower = logBase2(uSideLength);
|
||||
@ -44,8 +46,6 @@ namespace PolyVox
|
||||
m_tData = new VoxelType[uNoOfVoxels];
|
||||
|
||||
// Pass the chunk to the Pager to give it a chance to initialise it with any data
|
||||
if (m_pPager)
|
||||
{
|
||||
// From the coordinates of the chunk we deduce the coordinates of the contained voxels.
|
||||
Vector3DInt32 v3dLower = m_v3dChunkSpacePosition * static_cast<int32_t>(m_uSideLength);
|
||||
Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uSideLength - 1, m_uSideLength - 1, m_uSideLength - 1);
|
||||
@ -53,12 +53,6 @@ namespace PolyVox
|
||||
|
||||
// Page the data in
|
||||
m_pPager->pageIn(reg, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just fill with zeros
|
||||
std::fill(m_tData, m_tData + uNoOfVoxels, VoxelType());
|
||||
}
|
||||
|
||||
// We'll use this later to decide if data needs to be paged out again.
|
||||
m_bDataModified = false;
|
||||
@ -67,7 +61,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
PagedVolume<VoxelType>::Chunk::~Chunk()
|
||||
{
|
||||
if (m_pPager && m_bDataModified)
|
||||
if (m_bDataModified)
|
||||
{
|
||||
// From the coordinates of the chunk we deduce the coordinates of the contained voxels.
|
||||
Vector3DInt32 v3dLower = m_v3dChunkSpacePosition * static_cast<int32_t>(m_uSideLength);
|
||||
@ -118,7 +112,7 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::Chunk::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
|
||||
void PagedVolume<VoxelType>::Chunk::setVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
|
||||
{
|
||||
// This code is not usually expected to be called by the user, with the exception of when implementing paging
|
||||
// of uncompressed data. It's a performance critical code path so we use asserts rather than exceptions.
|
||||
@ -138,9 +132,9 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::Chunk::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue)
|
||||
void PagedVolume<VoxelType>::Chunk::setVoxel(const Vector3DUint16& v3dPos, VoxelType tValue)
|
||||
{
|
||||
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
|
@ -21,12 +21,12 @@ freely, subject to the following restrictions:
|
||||
distribution.
|
||||
*******************************************************************************/
|
||||
|
||||
#define CAN_GO_NEG_X(val) ((val > this->mVolume->getEnclosingRegion().getLowerX()) && (val % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_POS_X(val) ((val < this->mVolume->getEnclosingRegion().getUpperX()) && ((val + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_NEG_Y(val) ((val > this->mVolume->getEnclosingRegion().getLowerY()) && (val % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_POS_Y(val) ((val < this->mVolume->getEnclosingRegion().getUpperY()) && ((val + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_NEG_Z(val) ((val > this->mVolume->getEnclosingRegion().getLowerZ()) && (val % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_POS_Z(val) ((val < this->mVolume->getEnclosingRegion().getUpperZ()) && ((val + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_NEG_X(val) ((val % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_POS_X(val) (((val + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_NEG_Y(val) ((val % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_POS_Y(val) (((val + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_NEG_Z(val) ((val % this->mVolume->m_uChunkSideLength != 0))
|
||||
#define CAN_GO_POS_Z(val) (((val + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
@ -71,7 +71,7 @@ namespace PolyVox
|
||||
{
|
||||
for(uint8_t x = 0; x < uSize; ++x)
|
||||
{
|
||||
tValue = (std::min)(tValue, this->mVolume->getVoxelAt(this->mXPosInVolume + x, this->mYPosInVolume + y, this->mZPosInVolume + z));
|
||||
tValue = (std::min)(tValue, this->mVolume->getVoxel(this->mXPosInVolume + x, this->mYPosInVolume + y, this->mZPosInVolume + z));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,14 +82,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::getVoxel(void) const
|
||||
{
|
||||
if(this->isCurrentPositionValid())
|
||||
{
|
||||
return *mCurrentVoxel;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->getVoxelImpl(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -105,8 +98,6 @@ namespace PolyVox
|
||||
BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::setPosition(xPos, yPos, zPos);
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if(this->isCurrentPositionValid())
|
||||
{
|
||||
const int32_t uXChunk = this->mXPosInVolume >> this->mVolume->m_uChunkSideLengthPower;
|
||||
const int32_t uYChunk = this->mYPosInVolume >> this->mVolume->m_uChunkSideLengthPower;
|
||||
const int32_t uZChunk = this->mZPosInVolume >> this->mVolume->m_uChunkSideLengthPower;
|
||||
@ -123,25 +114,10 @@ namespace PolyVox
|
||||
|
||||
mCurrentVoxel = pCurrentChunk->m_tData + uVoxelIndexInChunk;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentVoxel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
bool PagedVolume<VoxelType>::Sampler::setVoxel(VoxelType tValue)
|
||||
{
|
||||
/*if(m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ)
|
||||
{
|
||||
*mCurrentVoxel = tValue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}*/
|
||||
|
||||
//Need to think what effect this has on any existing iterators.
|
||||
POLYVOX_THROW(not_implemented, "This function cannot be used on PagedVolume samplers.");
|
||||
return false;
|
||||
@ -150,14 +126,11 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::Sampler::movePositiveX(void)
|
||||
{
|
||||
// We'll need this in a moment...
|
||||
bool bIsOldPositionValid = this->isCurrentPositionValid();
|
||||
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::movePositiveX();
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if((this->isCurrentPositionValid()) && bIsOldPositionValid && ((this->mXPosInVolume) % this->mVolume->m_uChunkSideLength != 0))
|
||||
if(((this->mXPosInVolume) % this->mVolume->m_uChunkSideLength != 0))
|
||||
{
|
||||
//No need to compute new chunk.
|
||||
++mCurrentVoxel;
|
||||
@ -172,14 +145,11 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::Sampler::movePositiveY(void)
|
||||
{
|
||||
// We'll need this in a moment...
|
||||
bool bIsOldPositionValid = this->isCurrentPositionValid();
|
||||
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::movePositiveY();
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if((this->isCurrentPositionValid()) && bIsOldPositionValid && ((this->mYPosInVolume) % this->mVolume->m_uChunkSideLength != 0))
|
||||
if(((this->mYPosInVolume) % this->mVolume->m_uChunkSideLength != 0))
|
||||
{
|
||||
//No need to compute new chunk.
|
||||
mCurrentVoxel += this->mVolume->m_uChunkSideLength;
|
||||
@ -194,14 +164,11 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::Sampler::movePositiveZ(void)
|
||||
{
|
||||
// We'll need this in a moment...
|
||||
bool bIsOldPositionValid = this->isCurrentPositionValid();
|
||||
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::movePositiveZ();
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if((this->isCurrentPositionValid()) && bIsOldPositionValid && ((this->mZPosInVolume) % this->mVolume->m_uChunkSideLength != 0))
|
||||
if(((this->mZPosInVolume) % this->mVolume->m_uChunkSideLength != 0))
|
||||
{
|
||||
//No need to compute new chunk.
|
||||
mCurrentVoxel += this->mVolume->m_uChunkSideLength * this->mVolume->m_uChunkSideLength;
|
||||
@ -216,14 +183,11 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::Sampler::moveNegativeX(void)
|
||||
{
|
||||
// We'll need this in a moment...
|
||||
bool bIsOldPositionValid = this->isCurrentPositionValid();
|
||||
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::moveNegativeX();
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if((this->isCurrentPositionValid()) && bIsOldPositionValid && ((this->mXPosInVolume + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
if(((this->mXPosInVolume + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
{
|
||||
//No need to compute new chunk.
|
||||
--mCurrentVoxel;
|
||||
@ -238,14 +202,11 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::Sampler::moveNegativeY(void)
|
||||
{
|
||||
// We'll need this in a moment...
|
||||
bool bIsOldPositionValid = this->isCurrentPositionValid();
|
||||
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::moveNegativeY();
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if((this->isCurrentPositionValid()) && bIsOldPositionValid && ((this->mYPosInVolume + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
if(((this->mYPosInVolume + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
{
|
||||
//No need to compute new chunk.
|
||||
mCurrentVoxel -= this->mVolume->m_uChunkSideLength;
|
||||
@ -260,14 +221,11 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void PagedVolume<VoxelType>::Sampler::moveNegativeZ(void)
|
||||
{
|
||||
// We'll need this in a moment...
|
||||
bool bIsOldPositionValid = this->isCurrentPositionValid();
|
||||
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::moveNegativeZ();
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if((this->isCurrentPositionValid()) && bIsOldPositionValid && ((this->mZPosInVolume + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
if(((this->mZPosInVolume + 1) % this->mVolume->m_uChunkSideLength != 0))
|
||||
{
|
||||
//No need to compute new chunk.
|
||||
mCurrentVoxel -= this->mVolume->m_uChunkSideLength * this->mVolume->m_uChunkSideLength;
|
||||
@ -282,91 +240,91 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1nx1ny1nz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uChunkSideLength - this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1nx1ny0pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) )
|
||||
if(CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1nx1ny1pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uChunkSideLength + this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1nx0py1nz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1nx0py0pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) )
|
||||
if(CAN_GO_NEG_X(this->mXPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - 1);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1nx0py1pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1nx1py1nz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uChunkSideLength - this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1nx1py0pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) )
|
||||
if(CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1nx1py1pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uChunkSideLength + this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -374,91 +332,87 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel0px1ny1nz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uChunkSideLength - this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel0px1ny0pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) )
|
||||
if(CAN_GO_NEG_Y(this->mYPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel0px1ny1pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uChunkSideLength + this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel0px0py1nz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel0px0py0pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()))
|
||||
{
|
||||
return *mCurrentVoxel;
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel0px0py1pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel0px1py1nz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uChunkSideLength - this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel0px1py0pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) )
|
||||
if(CAN_GO_POS_Y(this->mYPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel0px1py1pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uChunkSideLength + this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -466,91 +420,91 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1px1ny1nz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uChunkSideLength - this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1px1ny0pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) )
|
||||
if(CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1px1ny1pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uChunkSideLength + this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1px0py1nz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1px0py0pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) )
|
||||
if(CAN_GO_POS_X(this->mXPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + 1);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1px0py1pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1px1py1nz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uChunkSideLength - this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1px1py0pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) )
|
||||
if(CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType PagedVolume<VoxelType>::Sampler::peekVoxel1px1py1pz(void) const
|
||||
{
|
||||
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
if(CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) )
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uChunkSideLength + this->mVolume->m_uChunkSideLength*this->mVolume->m_uChunkSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,8 @@ namespace PolyVox
|
||||
|
||||
inline VoxelType getVoxel(void) const;
|
||||
|
||||
bool isCurrentPositionValid(void) const;
|
||||
|
||||
void setPosition(const Vector3DInt32& v3dNewPos);
|
||||
void setPosition(int32_t xPos, int32_t yPos, int32_t zPos);
|
||||
inline bool setVoxel(VoxelType tValue);
|
||||
@ -105,6 +107,12 @@ namespace PolyVox
|
||||
|
||||
//Other current position information
|
||||
VoxelType* mCurrentVoxel;
|
||||
|
||||
//Whether the current position is inside the volume
|
||||
//FIXME - Replace these with flags
|
||||
bool m_bIsCurrentPositionValidInX;
|
||||
bool m_bIsCurrentPositionValidInY;
|
||||
bool m_bIsCurrentPositionValidInZ;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -115,31 +123,29 @@ namespace PolyVox
|
||||
/// Destructor
|
||||
~RawVolume();
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets the value used for voxels which are outside the volume
|
||||
VoxelType getBorderValue(void) const;
|
||||
/// Gets a Region representing the extents of the Volume.
|
||||
const Region& getEnclosingRegion(void) const;
|
||||
|
||||
/// Gets the width of the volume in voxels.
|
||||
int32_t getWidth(void) const;
|
||||
/// Gets the height of the volume in voxels.
|
||||
int32_t getHeight(void) const;
|
||||
/// Gets the depth of the volume in voxels.
|
||||
int32_t getDepth(void) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos) const;
|
||||
|
||||
/// Sets the value used for voxels which are outside the volume
|
||||
void setBorderValue(const VoxelType& tBorder);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue);
|
||||
|
||||
/// Calculates approximatly how many bytes of memory the volume is currently using.
|
||||
uint32_t calculateSizeInBytes(void);
|
||||
@ -154,13 +160,11 @@ namespace PolyVox
|
||||
private:
|
||||
void initialise(const Region& regValidRegion);
|
||||
|
||||
// A trick to implement specialization of template member functions in template classes. See http://stackoverflow.com/a/4951057
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const;
|
||||
//The size of the volume
|
||||
Region m_regValidRegion;
|
||||
|
||||
//The border value
|
||||
VoxelType m_tBorderValue;
|
||||
|
||||
//The voxel data
|
||||
VoxelType* m_pData;
|
||||
|
@ -29,7 +29,9 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
RawVolume<VoxelType>::RawVolume(const Region& regValid)
|
||||
:BaseVolume<VoxelType>(regValid)
|
||||
:BaseVolume<VoxelType>()
|
||||
, m_regValidRegion(regValid)
|
||||
, m_tBorderValue()
|
||||
{
|
||||
this->setBorderValue(VoxelType());
|
||||
|
||||
@ -74,39 +76,53 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
/// The border value is returned whenever an attempt is made to read a voxel which
|
||||
/// is outside the extents of the volume.
|
||||
/// \return The value used for voxels outside of the volume
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
|
||||
VoxelType RawVolume<VoxelType>::getBorderValue(void) const
|
||||
{
|
||||
// Simply call through to the real implementation
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<eWrapMode>(), tBorder);
|
||||
return m_tBorderValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
/// \return A Region representing the extent of the volume.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const
|
||||
const Region& RawVolume<VoxelType>::getEnclosingRegion(void) const
|
||||
{
|
||||
// Simply call through to the real implementation
|
||||
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
|
||||
return m_regValidRegion;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The width of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the width is 64.
|
||||
/// \sa getHeight(), getDepth()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t RawVolume<VoxelType>::getWidth(void) const
|
||||
{
|
||||
return m_regValidRegion.getUpperX() - m_regValidRegion.getLowerX() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The height of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the height is 64.
|
||||
/// \sa getWidth(), getDepth()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t RawVolume<VoxelType>::getHeight(void) const
|
||||
{
|
||||
return m_regValidRegion.getUpperY() - m_regValidRegion.getLowerY() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The depth of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the depth is 64.
|
||||
/// \sa getWidth(), getHeight()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t RawVolume<VoxelType>::getDepth(void) const
|
||||
{
|
||||
return m_regValidRegion.getUpperZ() - m_regValidRegion.getLowerZ() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -115,59 +131,17 @@ namespace PolyVox
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
switch(eWrapMode)
|
||||
if (this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
{
|
||||
case WrapModes::Validate:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Validate>(), tBorder);
|
||||
case WrapModes::Clamp:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Clamp>(), tBorder);
|
||||
case WrapModes::Border:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Border>(), tBorder);
|
||||
case WrapModes::AssumeValid:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder);
|
||||
default:
|
||||
// Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid wrap mode");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos The \c x position of the voxel
|
||||
/// \param uYPos The \c y position of the voxel
|
||||
/// \param uZPos The \c z position of the voxel
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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)))
|
||||
{
|
||||
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();
|
||||
const Region& regValidRegion = this->m_regValidRegion;
|
||||
int32_t iLocalXPos = uXPos - regValidRegion.getLowerX();
|
||||
int32_t iLocalYPos = uYPos - regValidRegion.getLowerY();
|
||||
int32_t iLocalZPos = uZPos - regValidRegion.getLowerZ();
|
||||
|
||||
return m_pData
|
||||
[
|
||||
@ -178,18 +152,29 @@ namespace PolyVox
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->getBorderValue();
|
||||
return m_tBorderValue;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelAt(const Vector3DInt32& v3dPos) const
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos) const
|
||||
{
|
||||
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param tBorder The value to use for voxels outside the volume.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::setBorderValue(const VoxelType& tBorder)
|
||||
{
|
||||
m_tBorderValue = tBorder;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -197,25 +182,14 @@ namespace PolyVox
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
/// \param uZPos the \c z position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
void RawVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
||||
{
|
||||
if((eWrapMode != WrapModes::Validate) && (eWrapMode != WrapModes::AssumeValid))
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Invalid wrap mode in call to setVoxel(). It must be 'None' or 'DontCheck'.");
|
||||
}
|
||||
|
||||
// This validation is skipped if the wrap mode is 'DontCheck'
|
||||
if(eWrapMode == WrapModes::Validate)
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
|
||||
if (this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
|
||||
}
|
||||
}
|
||||
|
||||
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
|
||||
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
|
||||
@ -233,57 +207,11 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos the 3D position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
void RawVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue)
|
||||
{
|
||||
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eWrapMode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos the \c x position of the voxel
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
/// \param uZPos the \c z position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \return whether the requested position is inside the volume
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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)))
|
||||
{
|
||||
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();
|
||||
|
||||
m_pData
|
||||
[
|
||||
iLocalXPos +
|
||||
iLocalYPos * this->getWidth() +
|
||||
iLocalZPos * this->getWidth() * this->getHeight()
|
||||
] = tValue;
|
||||
|
||||
//Return true to indicate that we modified a voxel.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos the 3D position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \return whether the requested position is inside the volume
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
bool RawVolume<VoxelType>::setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue)
|
||||
{
|
||||
return setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -310,10 +238,8 @@ namespace PolyVox
|
||||
//Create the data
|
||||
m_pData = new VoxelType[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());
|
||||
this->m_uShortestSideLength = (std::min)((std::min)(this->getWidth(),this->getHeight()),this->getDepth());
|
||||
this->m_fDiagonalLength = sqrtf(static_cast<float>(this->getWidth() * this->getWidth() + this->getHeight() * this->getHeight() + this->getDepth() * this->getDepth()));
|
||||
// Clear to zeros
|
||||
std::fill(m_pData, m_pData + this->getWidth() * this->getHeight()* this->getDepth(), VoxelType());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -324,67 +250,5 @@ namespace PolyVox
|
||||
{
|
||||
return this->getWidth() * this->getHeight() * this->getDepth() * sizeof(VoxelType);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const
|
||||
{
|
||||
// This function should never be called because one of the specialisations should always match.
|
||||
POLYVOX_ASSERT(false, "This function is not implemented and should never be called!");
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
|
||||
}
|
||||
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const
|
||||
{
|
||||
//Perform clamping
|
||||
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
|
||||
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
|
||||
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
|
||||
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
|
||||
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
|
||||
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
|
||||
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
{
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
else
|
||||
{
|
||||
return tBorder;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) const
|
||||
{
|
||||
const Region& regValidRegion = this->m_regValidRegion;
|
||||
int32_t iLocalXPos = uXPos - regValidRegion.getLowerX();
|
||||
int32_t iLocalYPos = uYPos - regValidRegion.getLowerY();
|
||||
int32_t iLocalZPos = uZPos - regValidRegion.getLowerZ();
|
||||
|
||||
return m_pData
|
||||
[
|
||||
iLocalXPos +
|
||||
iLocalYPos * this->getWidth() +
|
||||
iLocalZPos * this->getWidth() * this->getHeight()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,9 @@ namespace PolyVox
|
||||
RawVolume<VoxelType>::Sampler::Sampler(RawVolume<VoxelType>* volume)
|
||||
:BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >(volume)
|
||||
,mCurrentVoxel(0)
|
||||
, m_bIsCurrentPositionValidInX(false)
|
||||
, m_bIsCurrentPositionValidInY(false)
|
||||
, m_bIsCurrentPositionValidInZ(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -51,10 +54,16 @@ namespace PolyVox
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->getVoxelImpl(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
bool inline RawVolume<VoxelType>::Sampler::isCurrentPositionValid(void) const
|
||||
{
|
||||
return m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::Sampler::setPosition(const Vector3DInt32& v3dNewPos)
|
||||
{
|
||||
@ -67,6 +76,10 @@ namespace PolyVox
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::setPosition(xPos, yPos, zPos);
|
||||
|
||||
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(xPos);
|
||||
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(yPos);
|
||||
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(zPos);
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if(this->isCurrentPositionValid())
|
||||
{
|
||||
@ -111,6 +124,8 @@ namespace PolyVox
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::movePositiveX();
|
||||
|
||||
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(mXPosInVolume);
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if(this->isCurrentPositionValid() && bIsOldPositionValid )
|
||||
{
|
||||
@ -131,6 +146,8 @@ namespace PolyVox
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::movePositiveY();
|
||||
|
||||
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(mYPosInVolume);
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if(this->isCurrentPositionValid() && bIsOldPositionValid )
|
||||
{
|
||||
@ -151,6 +168,8 @@ namespace PolyVox
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::movePositiveZ();
|
||||
|
||||
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(mZPosInVolume);
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if(this->isCurrentPositionValid() && bIsOldPositionValid )
|
||||
{
|
||||
@ -171,6 +190,8 @@ namespace PolyVox
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::moveNegativeX();
|
||||
|
||||
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(mXPosInVolume);
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if(this->isCurrentPositionValid() && bIsOldPositionValid )
|
||||
{
|
||||
@ -191,6 +212,8 @@ namespace PolyVox
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::moveNegativeY();
|
||||
|
||||
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(mYPosInVolume);
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if(this->isCurrentPositionValid() && bIsOldPositionValid )
|
||||
{
|
||||
@ -211,6 +234,8 @@ namespace PolyVox
|
||||
// Base version updates position and validity flags.
|
||||
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::moveNegativeZ();
|
||||
|
||||
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(mZPosInVolume);
|
||||
|
||||
// Then we update the voxel pointer
|
||||
if(this->isCurrentPositionValid() && bIsOldPositionValid )
|
||||
{
|
||||
@ -229,7 +254,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -239,7 +264,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -249,7 +274,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -259,7 +284,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -269,7 +294,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -279,7 +304,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -289,7 +314,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -299,7 +324,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -309,7 +334,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -321,7 +346,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -331,7 +356,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -341,7 +366,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -351,7 +376,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -361,7 +386,7 @@ namespace PolyVox
|
||||
{
|
||||
return *mCurrentVoxel;
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -371,7 +396,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -381,7 +406,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -391,7 +416,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -401,7 +426,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -413,7 +438,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -423,7 +448,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -433,7 +458,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -443,7 +468,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -453,7 +478,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1);
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -463,7 +488,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -473,7 +498,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -483,7 +508,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -493,7 +518,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,9 +72,9 @@ namespace PolyVox
|
||||
{
|
||||
for(int32_t sx = m_regSrc.getLowerX(), dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); sx++,dx++)
|
||||
{
|
||||
const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxel(sx,sy,sz, WrapModes::AssumeValid); // FIXME use templatised version of getVoxel(), but watch out for Linux compile issues.
|
||||
const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxel(sx,sy,sz);
|
||||
const typename DstVolumeType::VoxelType& tDstVoxel = static_cast<typename DstVolumeType::VoxelType>(tSrcVoxel);
|
||||
m_pVolDst->setVoxelAt(dx,dy,dz,tDstVoxel);
|
||||
m_pVolDst->setVoxel(dx,dy,dz,tDstVoxel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,7 +130,7 @@ namespace PolyVox
|
||||
typename SrcVolumeType::VoxelType tInterpolatedValue = trilerp<float>(voxel000,voxel100,voxel010,voxel110,voxel001,voxel101,voxel011,voxel111,sx,sy,sz);
|
||||
|
||||
typename DstVolumeType::VoxelType result = static_cast<typename DstVolumeType::VoxelType>(tInterpolatedValue);
|
||||
m_pVolDst->setVoxelAt(dx,dy,dz,result);
|
||||
m_pVolDst->setVoxel(dx,dy,dz,result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ bool testVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos)
|
||||
return false;
|
||||
}
|
||||
|
||||
typename VolumeType::VoxelType voxel = volData->getVoxel(v3dPos, WrapModes::Validate); // FIXME use templatised version of getVoxel(), but watch out for Linux compile issues.
|
||||
typename VolumeType::VoxelType voxel = volData->getVoxel(v3dPos);
|
||||
if(voxel != 0)
|
||||
{
|
||||
return false;
|
||||
@ -92,7 +92,7 @@ void TestAStarPathfinder::testExecute()
|
||||
for(int x = 0; x < uVolumeSideLength; x++)
|
||||
{
|
||||
uint8_t solidVoxel(0);
|
||||
volData.setVoxelAt(x,y,z,solidVoxel);
|
||||
volData.setVoxel(x,y,z,solidVoxel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,7 +105,7 @@ void TestAStarPathfinder::testExecute()
|
||||
for(int x = 4; x < 12; x++)
|
||||
{
|
||||
uint8_t solidVoxel(1);
|
||||
volData.setVoxelAt(x,y,z,solidVoxel);
|
||||
volData.setVoxel(x,y,z,solidVoxel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ freely, subject to the following restrictions:
|
||||
#include "TestAmbientOcclusionGenerator.h"
|
||||
|
||||
#include "PolyVox/AmbientOcclusionCalculator.h"
|
||||
#include "PolyVox/PagedVolume.h"
|
||||
#include "PolyVox/RawVolume.h"
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
@ -49,7 +49,7 @@ void TestAmbientOcclusionGenerator::testExecute()
|
||||
const int32_t g_uVolumeSideLength = 64;
|
||||
|
||||
//Create empty volume
|
||||
PagedVolume<uint8_t> volData(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(g_uVolumeSideLength - 1, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1)));
|
||||
RawVolume<uint8_t> volData(Region(0, 0, 0, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1));
|
||||
|
||||
//Create two solid walls at opposite sides of the volume
|
||||
for (int32_t z = 0; z < g_uVolumeSideLength; z++)
|
||||
@ -60,7 +60,7 @@ void TestAmbientOcclusionGenerator::testExecute()
|
||||
{
|
||||
for (int32_t x = 0; x < g_uVolumeSideLength; x++)
|
||||
{
|
||||
volData.setVoxelAt(x, y, z, 1);
|
||||
volData.setVoxel(x, y, z, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ freely, subject to the following restrictions:
|
||||
#include "TestCubicSurfaceExtractor.h"
|
||||
|
||||
#include "PolyVox/Density.h"
|
||||
#include "PolyVox/FilePager.h"
|
||||
#include "PolyVox/Material.h"
|
||||
#include "PolyVox/MaterialDensityPair.h"
|
||||
#include "PolyVox/RawVolume.h"
|
||||
@ -60,11 +61,8 @@ public:
|
||||
|
||||
// Runs the surface extractor for a given type.
|
||||
template <typename VolumeType>
|
||||
VolumeType* createAndFillVolumeWithNoise(int32_t iVolumeSideLength, typename VolumeType::VoxelType minValue, typename VolumeType::VoxelType maxValue)
|
||||
void createAndFillVolumeWithNoise(VolumeType& volData, int32_t iVolumeSideLength, typename VolumeType::VoxelType minValue, typename VolumeType::VoxelType maxValue)
|
||||
{
|
||||
//Create empty volume
|
||||
VolumeType* volData = new VolumeType(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(iVolumeSideLength - 1, iVolumeSideLength - 1, iVolumeSideLength - 1)));
|
||||
|
||||
// Set up a random number generator
|
||||
std::mt19937 rng;
|
||||
|
||||
@ -78,7 +76,7 @@ VolumeType* createAndFillVolumeWithNoise(int32_t iVolumeSideLength, typename Vol
|
||||
if (minValue == maxValue)
|
||||
{
|
||||
// In this case we are filling the whole volume with a single value.
|
||||
volData->setVoxelAt(x, y, z, minValue);
|
||||
volData.setVoxel(x, y, z, minValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -86,13 +84,11 @@ VolumeType* createAndFillVolumeWithNoise(int32_t iVolumeSideLength, typename Vol
|
||||
// We can't use std distributions because they vary between platforms (breaking tests).
|
||||
int voxelValue = (rng() % (maxValue - minValue + 1)) + minValue; // +1 for inclusive bounds
|
||||
|
||||
volData->setVoxelAt(x, y, z, static_cast<typename VolumeType::VoxelType>(voxelValue));
|
||||
volData.setVoxel(x, y, z, static_cast<typename VolumeType::VoxelType>(voxelValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return volData;
|
||||
}
|
||||
|
||||
// Runs the surface extractor for a given type.
|
||||
@ -100,7 +96,8 @@ template <typename VolumeType>
|
||||
VolumeType* createAndFillVolumeRealistic(int32_t iVolumeSideLength)
|
||||
{
|
||||
//Create empty volume
|
||||
VolumeType* volData = new VolumeType(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(iVolumeSideLength - 1, iVolumeSideLength - 1, iVolumeSideLength - 1)));
|
||||
FilePager<uint32_t>* filePager = new FilePager<uint32_t>();
|
||||
VolumeType* volData = new VolumeType(filePager);
|
||||
|
||||
//Fill the volume with data
|
||||
for (int32_t z = 0; z < iVolumeSideLength; z++)
|
||||
@ -113,11 +110,11 @@ VolumeType* createAndFillVolumeRealistic(int32_t iVolumeSideLength)
|
||||
// that it's not empty/random data, and should allow significant decimation to be performed.
|
||||
if ((x ^ y) & 0x01)
|
||||
{
|
||||
volData->setVoxelAt(x, y, z, 0);
|
||||
volData->setVoxel(x, y, z, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
volData->setVoxelAt(x, y, z, 1);
|
||||
volData->setVoxel(x, y, z, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -128,38 +125,46 @@ VolumeType* createAndFillVolumeRealistic(int32_t iVolumeSideLength)
|
||||
|
||||
void TestCubicSurfaceExtractor::testBehaviour()
|
||||
{
|
||||
int32_t iVolumeSideLength = 32;
|
||||
|
||||
// Test with default mesh and contoller types.
|
||||
auto uint8Vol = createAndFillVolumeWithNoise< PagedVolume<uint8_t> >(32, 0, 2);
|
||||
auto uint8Mesh = extractCubicMesh(uint8Vol, uint8Vol->getEnclosingRegion());
|
||||
RawVolume<uint8_t> uint8Vol(Region(0, 0, 0, iVolumeSideLength - 1, iVolumeSideLength - 1, iVolumeSideLength - 1));
|
||||
createAndFillVolumeWithNoise(uint8Vol, 32, 0, 2);
|
||||
auto uint8Mesh = extractCubicMesh(&uint8Vol, uint8Vol.getEnclosingRegion());
|
||||
QCOMPARE(uint8Mesh.getNoOfVertices(), uint32_t(57544));
|
||||
QCOMPARE(uint8Mesh.getNoOfIndices(), uint32_t(215304));
|
||||
|
||||
// Test with default mesh type but user-provided controller.
|
||||
auto int8Vol = createAndFillVolumeWithNoise< PagedVolume<int8_t> >(32, 0, 2);
|
||||
auto int8Mesh = extractCubicMesh(int8Vol, int8Vol->getEnclosingRegion(), CustomIsQuadNeeded<int8_t>());
|
||||
RawVolume<int8_t> int8Vol(Region(0, 0, 0, iVolumeSideLength - 1, iVolumeSideLength - 1, iVolumeSideLength - 1));
|
||||
createAndFillVolumeWithNoise(int8Vol, 32, 0, 2);
|
||||
auto int8Mesh = extractCubicMesh(&int8Vol, int8Vol.getEnclosingRegion(), CustomIsQuadNeeded<int8_t>());
|
||||
QCOMPARE(int8Mesh.getNoOfVertices(), uint32_t(29106));
|
||||
QCOMPARE(int8Mesh.getNoOfIndices(), uint32_t(178566));
|
||||
|
||||
// Test with default controller but user-provided mesh.
|
||||
auto uint32Vol = createAndFillVolumeWithNoise< PagedVolume<uint32_t> >(32, 0, 2);
|
||||
RawVolume<uint32_t> uint32Vol(Region(0, 0, 0, iVolumeSideLength - 1, iVolumeSideLength - 1, iVolumeSideLength - 1));
|
||||
createAndFillVolumeWithNoise(uint32Vol, 32, 0, 2);
|
||||
Mesh< CubicVertex< uint32_t >, uint16_t > uint32Mesh;
|
||||
extractCubicMeshCustom(uint32Vol, uint32Vol->getEnclosingRegion(), &uint32Mesh);
|
||||
extractCubicMeshCustom(&uint32Vol, uint32Vol.getEnclosingRegion(), &uint32Mesh);
|
||||
QCOMPARE(uint32Mesh.getNoOfVertices(), uint16_t(57544));
|
||||
QCOMPARE(uint32Mesh.getNoOfIndices(), uint32_t(215304));
|
||||
|
||||
// Test with both mesh and controller being provided by the user.
|
||||
auto int32Vol = createAndFillVolumeWithNoise< PagedVolume<int32_t> >(32, 0, 2);
|
||||
RawVolume<int32_t> int32Vol(Region(0, 0, 0, iVolumeSideLength - 1, iVolumeSideLength - 1, iVolumeSideLength - 1));
|
||||
createAndFillVolumeWithNoise(int32Vol, 32, 0, 2);
|
||||
Mesh< CubicVertex< int32_t >, uint16_t > int32Mesh;
|
||||
extractCubicMeshCustom(int32Vol, int32Vol->getEnclosingRegion(), &int32Mesh, CustomIsQuadNeeded<int32_t>());
|
||||
extractCubicMeshCustom(&int32Vol, int32Vol.getEnclosingRegion(), &int32Mesh, CustomIsQuadNeeded<int32_t>());
|
||||
QCOMPARE(int32Mesh.getNoOfVertices(), uint16_t(29106));
|
||||
QCOMPARE(int32Mesh.getNoOfIndices(), uint32_t(178566));
|
||||
}
|
||||
|
||||
void TestCubicSurfaceExtractor::testEmptyVolumePerformance()
|
||||
{
|
||||
auto emptyVol = createAndFillVolumeWithNoise< PagedVolume<uint32_t> >(128, 0, 0);
|
||||
FilePager<uint32_t>* filePager = new FilePager<uint32_t>();
|
||||
PagedVolume<uint32_t> emptyVol(filePager);
|
||||
createAndFillVolumeWithNoise(emptyVol, 128, 0, 0);
|
||||
Mesh< CubicVertex< uint32_t >, uint16_t > emptyMesh;
|
||||
QBENCHMARK{ extractCubicMeshCustom(emptyVol, Region(32, 32, 32, 63, 63, 63), &emptyMesh); }
|
||||
QBENCHMARK{ extractCubicMeshCustom(&emptyVol, Region(32, 32, 32, 63, 63, 63), &emptyMesh); }
|
||||
QCOMPARE(emptyMesh.getNoOfVertices(), uint16_t(0));
|
||||
}
|
||||
|
||||
@ -173,9 +178,11 @@ void TestCubicSurfaceExtractor::testRealisticVolumePerformance()
|
||||
|
||||
void TestCubicSurfaceExtractor::testNoiseVolumePerformance()
|
||||
{
|
||||
auto noiseVol = createAndFillVolumeWithNoise< PagedVolume<uint32_t> >(128, 0, 2);
|
||||
FilePager<uint32_t>* filePager = new FilePager<uint32_t>();
|
||||
PagedVolume<uint32_t> noiseVol(filePager);
|
||||
createAndFillVolumeWithNoise(noiseVol, 128, 0, 2);
|
||||
Mesh< CubicVertex< uint32_t >, uint16_t > noiseMesh;
|
||||
QBENCHMARK{ extractCubicMeshCustom(noiseVol, Region(32, 32, 32, 63, 63, 63), &noiseMesh); }
|
||||
QBENCHMARK{ extractCubicMeshCustom(&noiseVol, Region(32, 32, 32, 63, 63, 63), &noiseMesh); }
|
||||
QCOMPARE(noiseMesh.getNoOfVertices(), uint16_t(57905));
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ void TestLowPassFilter::testExecute()
|
||||
if(x % 2 == 0)
|
||||
{
|
||||
Density8 voxel(32);
|
||||
volData.setVoxelAt(x, y, z, voxel);
|
||||
volData.setVoxel(x, y, z, voxel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ freely, subject to the following restrictions:
|
||||
#include "TestPicking.h"
|
||||
|
||||
#include "PolyVox/Picking.h"
|
||||
#include "PolyVox/PagedVolume.h"
|
||||
#include "PolyVox/RawVolume.h"
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
@ -34,7 +34,7 @@ void TestPicking::testExecute()
|
||||
{
|
||||
const int32_t uVolumeSideLength = 32;
|
||||
|
||||
PagedVolume<int8_t> volData(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(uVolumeSideLength - 1, uVolumeSideLength - 1, uVolumeSideLength - 1)));
|
||||
RawVolume<int8_t> volData(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(uVolumeSideLength - 1, uVolumeSideLength - 1, uVolumeSideLength - 1)));
|
||||
for (int32_t z = 0; z < uVolumeSideLength; z++)
|
||||
{
|
||||
for (int32_t y = 0; y < uVolumeSideLength; y++)
|
||||
@ -43,11 +43,11 @@ void TestPicking::testExecute()
|
||||
{
|
||||
if((x > uVolumeSideLength/2)) //x > 16 is filled
|
||||
{
|
||||
volData.setVoxelAt(x, y, z, 100);
|
||||
volData.setVoxel(x, y, z, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
volData.setVoxelAt(x, y, z, 0);
|
||||
volData.setVoxel(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ freely, subject to the following restrictions:
|
||||
|
||||
#include "PolyVox/Density.h"
|
||||
#include "PolyVox/Raycast.h"
|
||||
#include "PolyVox/PagedVolume.h"
|
||||
#include "PolyVox/RawVolume.h"
|
||||
|
||||
#include "PolyVox/Impl/RandomUnitVectors.h"
|
||||
|
||||
@ -47,7 +47,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const PagedVolume<int8_t>::Sampler& sampler)
|
||||
bool operator()(const RawVolume<int8_t>::Sampler& sampler)
|
||||
{
|
||||
m_uVoxelsTouched++;
|
||||
|
||||
@ -73,7 +73,7 @@ void TestRaycast::testExecute()
|
||||
const int32_t uVolumeSideLength = 32;
|
||||
|
||||
//Create a hollow volume, with solid sides on x and y but with open ends in z.
|
||||
PagedVolume<int8_t> volData(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(uVolumeSideLength - 1, uVolumeSideLength - 1, uVolumeSideLength - 1)));
|
||||
RawVolume<int8_t> volData(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(uVolumeSideLength - 1, uVolumeSideLength - 1, uVolumeSideLength - 1)));
|
||||
for (int32_t z = 0; z < uVolumeSideLength; z++)
|
||||
{
|
||||
for (int32_t y = 0; y < uVolumeSideLength; y++)
|
||||
@ -82,11 +82,11 @@ void TestRaycast::testExecute()
|
||||
{
|
||||
if((x == 0) || (x == uVolumeSideLength-1) || (y == 0) || (y == uVolumeSideLength-1))
|
||||
{
|
||||
volData.setVoxelAt(x, y, z, 100);
|
||||
volData.setVoxel(x, y, z, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
volData.setVoxelAt(x, y, z, -100);
|
||||
volData.setVoxel(x, y, z, -100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,10 +103,8 @@ VolumeType* createAndFillVolume(void)
|
||||
{
|
||||
const int32_t uVolumeSideLength = 64;
|
||||
|
||||
FilePager<typename VolumeType::VoxelType>* pager = new FilePager<typename VolumeType::VoxelType>(".");
|
||||
|
||||
//Create empty volume
|
||||
VolumeType* volData = new VolumeType(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(uVolumeSideLength - 1, uVolumeSideLength - 1, uVolumeSideLength - 1)), pager);
|
||||
VolumeType* volData = new VolumeType(Region(0, 0, 0, uVolumeSideLength - 1, uVolumeSideLength - 1, uVolumeSideLength - 1));
|
||||
|
||||
// Fill
|
||||
for (int32_t z = 0; z < uVolumeSideLength; z++)
|
||||
@ -120,7 +118,7 @@ VolumeType* createAndFillVolume(void)
|
||||
typename VolumeType::VoxelType voxelValue;
|
||||
writeDensityValueToVoxel<typename VolumeType::VoxelType>(x + y + z, voxelValue);
|
||||
writeMaterialValueToVoxel<typename VolumeType::VoxelType>(z > uVolumeSideLength / 2 ? 42 : 79, voxelValue);
|
||||
volData->setVoxelAt(x, y, z, voxelValue);
|
||||
volData->setVoxel(x, y, z, voxelValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -134,7 +132,7 @@ VolumeType* createAndFillVolumeWithNoise(int32_t iVolumeSideLength, float minVal
|
||||
FilePager<float>* pager = new FilePager<float>(".");
|
||||
|
||||
//Create empty volume
|
||||
VolumeType* volData = new VolumeType(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(iVolumeSideLength - 1, iVolumeSideLength - 1, iVolumeSideLength - 1)), pager);
|
||||
VolumeType* volData = new VolumeType(pager);
|
||||
|
||||
// Set up a random number generator
|
||||
std::mt19937 rng;
|
||||
@ -150,7 +148,7 @@ VolumeType* createAndFillVolumeWithNoise(int32_t iVolumeSideLength, float minVal
|
||||
float voxelValue = static_cast<float>(rng()) / static_cast<float>(std::numeric_limits<int32_t>::max()); // Float in range 0.0 to 1.0
|
||||
voxelValue = voxelValue * (maxValue - minValue) + minValue; // Float in range minValue to maxValue
|
||||
|
||||
volData->setVoxelAt(x, y, z, voxelValue);
|
||||
volData->setVoxel(x, y, z, voxelValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,7 +166,7 @@ void TestSurfaceExtractor::testBehaviour()
|
||||
// Of course, the use of a custom controller will also make a significant diference, but this probably does need investigating further in the future.
|
||||
|
||||
// This basic test just uses the default controller and automatically generates a mesh of the appropriate type.
|
||||
auto uintVol = createAndFillVolume< PagedVolume<uint8_t> >();
|
||||
auto uintVol = createAndFillVolume< RawVolume<uint8_t> >();
|
||||
auto uintMesh = extractMarchingCubesMesh(uintVol, uintVol->getEnclosingRegion());
|
||||
QCOMPARE(uintMesh.getNoOfVertices(), uint32_t(12096)); // Verifies size of mesh and that we have 32-bit indices
|
||||
QCOMPARE(uintMesh.getNoOfIndices(), uint32_t(35157)); // Verifies size of mesh
|
||||
@ -176,7 +174,7 @@ void TestSurfaceExtractor::testBehaviour()
|
||||
QCOMPARE(uintMesh.getVertex(100).data, uint8_t(1)); // Not really meaningful for a primative type
|
||||
|
||||
// This test makes use of a custom controller
|
||||
auto floatVol = createAndFillVolume< PagedVolume<float> >();
|
||||
auto floatVol = createAndFillVolume< RawVolume<float> >();
|
||||
CustomMarchingCubesController floatCustomController;
|
||||
auto floatMesh = extractMarchingCubesMesh(floatVol, floatVol->getEnclosingRegion(), floatCustomController);
|
||||
QCOMPARE(floatMesh.getNoOfVertices(), uint32_t(16113)); // Verifies size of mesh and that we have 32-bit indices
|
||||
@ -186,7 +184,7 @@ void TestSurfaceExtractor::testBehaviour()
|
||||
|
||||
// This test makes use of a user provided mesh. It uses the default controller, but we have to explicitly provide this because C++ won't let us
|
||||
// use a default for the second-to-last parameter but noot use a default for the last parameter.
|
||||
auto intVol = createAndFillVolume< PagedVolume<int8_t> >();
|
||||
auto intVol = createAndFillVolume< RawVolume<int8_t> >();
|
||||
Mesh< MarchingCubesVertex< int8_t >, uint16_t > intMesh;
|
||||
extractMarchingCubesMeshCustom(intVol, intVol->getEnclosingRegion(), &intMesh);
|
||||
QCOMPARE(intMesh.getNoOfVertices(), uint16_t(11718)); // Verifies size of mesh and that we have 16-bit indices
|
||||
@ -195,7 +193,7 @@ void TestSurfaceExtractor::testBehaviour()
|
||||
QCOMPARE(intMesh.getVertex(100).data, int8_t(1)); // Not really meaningful for a primative type
|
||||
|
||||
// This test makes use of a user-provided mesh and also a custom controller.
|
||||
auto doubleVol = createAndFillVolume< PagedVolume<double> >();
|
||||
auto doubleVol = createAndFillVolume< RawVolume<double> >();
|
||||
CustomMarchingCubesController doubleCustomController;
|
||||
Mesh< MarchingCubesVertex< double >, uint16_t > doubleMesh;
|
||||
extractMarchingCubesMeshCustom(doubleVol, doubleVol->getEnclosingRegion(), &doubleMesh, doubleCustomController);
|
||||
@ -205,7 +203,7 @@ void TestSurfaceExtractor::testBehaviour()
|
||||
QCOMPARE(doubleMesh.getVertex(100).data, double(1.0f)); // Not really meaningful for a primative type
|
||||
|
||||
// This test ensures the extractor works on a non-primitive voxel type.
|
||||
auto materialVol = createAndFillVolume< PagedVolume<MaterialDensityPair88> >();
|
||||
auto materialVol = createAndFillVolume< RawVolume<MaterialDensityPair88> >();
|
||||
auto materialMesh = extractMarchingCubesMesh(materialVol, materialVol->getEnclosingRegion());
|
||||
QCOMPARE(materialMesh.getNoOfVertices(), uint32_t(12096)); // Verifies size of mesh and that we have 32-bit indices
|
||||
QCOMPARE(materialMesh.getNoOfIndices(), uint32_t(35157)); // Verifies size of mesh
|
||||
|
@ -62,8 +62,8 @@ public:
|
||||
|
||||
/// Constructor for creating a fixed size volume.
|
||||
VolumeSubclass(const Region& regValid)
|
||||
:BaseVolume<VoxelType>(regValid)
|
||||
, mVolumeData(this->getWidth(), this->getHeight(), this->getDepth())
|
||||
:BaseVolume<VoxelType>()
|
||||
, mVolumeData(regValid.getWidthInVoxels(), regValid.getHeightInVoxels(), regValid.getDepthInVoxels())
|
||||
{
|
||||
//mVolumeData.resize(ArraySizes(this->getWidth())(this->getHeight())(this->getDepth()));
|
||||
}
|
||||
@ -71,83 +71,30 @@ public:
|
||||
~VolumeSubclass() {};
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
// FIXME: This templatised version is implemented in terms of the not template version. This is strange
|
||||
// from a peformance point of view but it's just because we were encountering some compile issues on GCC.
|
||||
return getVoxel(uXPos, uYPos, uZPos, eWrapMode, tBorder);
|
||||
}
|
||||
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const
|
||||
{
|
||||
// Simply call through to the real implementation
|
||||
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
|
||||
}
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const
|
||||
{
|
||||
switch(eWrapMode)
|
||||
{
|
||||
case WrapModes::Validate:
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
|
||||
}
|
||||
|
||||
return mVolumeData(uXPos, uYPos, uZPos);
|
||||
}
|
||||
case WrapModes::Clamp:
|
||||
{
|
||||
//Perform clamping
|
||||
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
|
||||
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
|
||||
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
|
||||
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
|
||||
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
|
||||
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
|
||||
return mVolumeData(uXPos, uYPos, uZPos);
|
||||
}
|
||||
case WrapModes::Border:
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
if ((uXPos < mVolumeData.getDimension(0)) && (uYPos < mVolumeData.getDimension(1)) && (uZPos < mVolumeData.getDimension(2)))
|
||||
{
|
||||
return mVolumeData(uXPos, uYPos, uZPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tBorder;
|
||||
}
|
||||
}
|
||||
case WrapModes::AssumeValid:
|
||||
{
|
||||
return mVolumeData(uXPos, uYPos, uZPos);
|
||||
}
|
||||
default:
|
||||
{
|
||||
// Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid wrap mode");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos) const
|
||||
{
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
/// Sets the value used for voxels which are outside the volume
|
||||
void setBorderValue(const VoxelType& tBorder) { }
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
||||
bool setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)))
|
||||
if ((uXPos < mVolumeData.getDimension(0)) && (uYPos < mVolumeData.getDimension(1)) && (uZPos < mVolumeData.getDimension(2)))
|
||||
{
|
||||
mVolumeData(uXPos, uYPos, uZPos) = tValue;
|
||||
return true;
|
||||
@ -158,7 +105,7 @@ public:
|
||||
}
|
||||
}
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue) { return setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); }
|
||||
bool setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue) { return setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); }
|
||||
|
||||
/// Calculates approximatly how many bytes of memory the volume is currently using.
|
||||
uint32_t calculateSizeInBytes(void) { return 0; }
|
||||
@ -172,21 +119,22 @@ private:
|
||||
|
||||
void TestVolumeSubclass::testExtractSurface()
|
||||
{
|
||||
VolumeSubclass<Material8> volumeSubclass(Region(0,0,0,16,16,16));
|
||||
Region region(0, 0, 0, 16, 16, 16);
|
||||
VolumeSubclass<Material8> volumeSubclass(region);
|
||||
|
||||
for(int32_t z = 0; z < volumeSubclass.getDepth() / 2; z++)
|
||||
for (int32_t z = 0; z < region.getDepthInVoxels() / 2; z++)
|
||||
{
|
||||
for(int32_t y = 0; y < volumeSubclass.getHeight(); y++)
|
||||
for (int32_t y = 0; y < region.getHeightInVoxels(); y++)
|
||||
{
|
||||
for(int32_t x = 0; x < volumeSubclass.getWidth(); x++)
|
||||
for (int32_t x = 0; x < region.getWidthInVoxels(); x++)
|
||||
{
|
||||
Material8 mat(1);
|
||||
volumeSubclass.setVoxelAt(Vector3DInt32(x,y,z),mat);
|
||||
volumeSubclass.setVoxel(Vector3DInt32(x,y,z),mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto result = extractCubicMesh(&volumeSubclass, volumeSubclass.getEnclosingRegion());
|
||||
auto result = extractCubicMesh(&volumeSubclass, region);
|
||||
|
||||
QCOMPARE(result.getNoOfVertices(), static_cast<uint32_t>(8));
|
||||
}
|
||||
|
@ -46,18 +46,15 @@ inline int32_t cantorTupleFunction(int32_t previousResult, int32_t value)
|
||||
// We allow user provided offset in this function so we can test the case when all samples are inside a volume and also the case when some samples are outside.
|
||||
// This is important because samplers are often slower when outside the volume as they have to fall back on directly accessing the volume data.
|
||||
template <typename VolumeType>
|
||||
int32_t testDirectAccessWithWrappingForwards(const VolumeType* volume, int lowXOffset, int lowYOffset, int lowZOffset, int highXOffset, int highYOffset, int highZOffset)
|
||||
int32_t testDirectAccessWithWrappingForwards(const VolumeType* volume, Region region)
|
||||
{
|
||||
int32_t result = 0;
|
||||
|
||||
// If we know that we are only iterating over voxels internal to the volume then we can avoid calling the 'wrapping' function. This should be faster.
|
||||
bool bAllVoxelsInternal = (lowXOffset > 0) && (lowYOffset > 0) && (lowZOffset > 0) && (highXOffset < 0) && (highYOffset < 0) && (highZOffset < 0);
|
||||
|
||||
for(int z = volume->getEnclosingRegion().getLowerZ() + lowZOffset; z <= volume->getEnclosingRegion().getUpperZ() + highZOffset; z++)
|
||||
for (int z = region.getLowerZ(); z <= region.getUpperZ(); z++)
|
||||
{
|
||||
for(int y = volume->getEnclosingRegion().getLowerY() + lowYOffset; y <= volume->getEnclosingRegion().getUpperY() + highYOffset; y++)
|
||||
for (int y = region.getLowerY(); y <= region.getUpperY(); y++)
|
||||
{
|
||||
for(int x = volume->getEnclosingRegion().getLowerX() + lowXOffset; x <= volume->getEnclosingRegion().getUpperX() + highXOffset; x++)
|
||||
for (int x = region.getLowerX(); x <= region.getUpperX(); x++)
|
||||
{
|
||||
//Three level loop now processes 27 voxel neighbourhood
|
||||
for(int innerZ = -1; innerZ <=1; innerZ++)
|
||||
@ -65,18 +62,9 @@ int32_t testDirectAccessWithWrappingForwards(const VolumeType* volume, int lowXO
|
||||
for(int innerY = -1; innerY <=1; innerY++)
|
||||
{
|
||||
for(int innerX = -1; innerX <=1; innerX++)
|
||||
{
|
||||
// Deeply nested 'if', but this is just a unit test and we should still
|
||||
// see some performance improvement by skipping the wrapping versions.
|
||||
if(bAllVoxelsInternal)
|
||||
{
|
||||
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ, WrapModes::Border, 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//End of inner loops
|
||||
@ -88,7 +76,7 @@ int32_t testDirectAccessWithWrappingForwards(const VolumeType* volume, int lowXO
|
||||
}
|
||||
|
||||
template <typename VolumeType>
|
||||
int32_t testSamplersWithWrappingForwards(VolumeType* volume, int lowXOffset, int lowYOffset, int lowZOffset, int highXOffset, int highYOffset, int highZOffset)
|
||||
int32_t testSamplersWithWrappingForwards(VolumeType* volume, Region region)
|
||||
{
|
||||
int32_t result = 0;
|
||||
|
||||
@ -97,18 +85,14 @@ int32_t testSamplersWithWrappingForwards(VolumeType* volume, int lowXOffset, int
|
||||
typename VolumeType::Sampler ySampler(volume);
|
||||
typename VolumeType::Sampler zSampler(volume);
|
||||
|
||||
xSampler.setWrapMode(WrapModes::Border, 3);
|
||||
ySampler.setWrapMode(WrapModes::Border, 3);
|
||||
zSampler.setWrapMode(WrapModes::Border, 3);
|
||||
|
||||
zSampler.setPosition(volume->getEnclosingRegion().getLowerX() + lowXOffset, volume->getEnclosingRegion().getLowerY() + lowYOffset, volume->getEnclosingRegion().getLowerZ() + lowZOffset);
|
||||
for(int z = volume->getEnclosingRegion().getLowerZ() + lowZOffset; z <= volume->getEnclosingRegion().getUpperZ() + highZOffset; z++)
|
||||
zSampler.setPosition(region.getLowerX(), region.getLowerY(), region.getLowerZ());
|
||||
for (int z = region.getLowerZ(); z <= region.getUpperZ(); z++)
|
||||
{
|
||||
ySampler = zSampler;
|
||||
for(int y = volume->getEnclosingRegion().getLowerY() + lowYOffset; y <= volume->getEnclosingRegion().getUpperY() + highYOffset; y++)
|
||||
for (int y = region.getLowerY(); y <= region.getUpperY(); y++)
|
||||
{
|
||||
xSampler = ySampler;
|
||||
for(int x = volume->getEnclosingRegion().getLowerX() + lowXOffset; x <= volume->getEnclosingRegion().getUpperX() + highXOffset; x++)
|
||||
for (int x = region.getLowerX(); x <= region.getUpperX(); x++)
|
||||
{
|
||||
xSampler.setPosition(x, y, z); // HACK - Accessing a volume through multiple samplers currently breaks the PagedVolume.
|
||||
|
||||
@ -159,18 +143,15 @@ int32_t testSamplersWithWrappingForwards(VolumeType* volume, int lowXOffset, int
|
||||
// We allow user provided offset in this function so we can test the case when all samples are inside a volume and also the case when some samples are outside.
|
||||
// This is important because samplers are often slower when outside the volume as they have to fall back on directly accessing the volume data.
|
||||
template <typename VolumeType>
|
||||
int32_t testDirectAccessWithWrappingBackwards(const VolumeType* volume, int lowXOffset, int lowYOffset, int lowZOffset, int highXOffset, int highYOffset, int highZOffset)
|
||||
int32_t testDirectAccessWithWrappingBackwards(const VolumeType* volume, Region region)
|
||||
{
|
||||
int32_t result = 0;
|
||||
|
||||
// If we know that we are only iterating over voxels internal to the volume then we can avoid calling the 'wrapping' function. This should be faster.
|
||||
bool bAllVoxelsInternal = (lowXOffset > 0) && (lowYOffset > 0) && (lowZOffset > 0) && (highXOffset < 0) && (highYOffset < 0) && (highZOffset < 0);
|
||||
|
||||
for(int z = volume->getEnclosingRegion().getUpperZ() + highZOffset; z >= volume->getEnclosingRegion().getLowerZ() + lowZOffset; z--)
|
||||
for (int z = region.getUpperZ(); z >= region.getLowerZ(); z--)
|
||||
{
|
||||
for(int y = volume->getEnclosingRegion().getUpperY() + highYOffset; y >= volume->getEnclosingRegion().getLowerY() + lowYOffset; y--)
|
||||
for (int y = region.getUpperY(); y >= region.getLowerY(); y--)
|
||||
{
|
||||
for(int x = volume->getEnclosingRegion().getUpperX() + highXOffset; x >= volume->getEnclosingRegion().getLowerX() + lowXOffset; x--)
|
||||
for (int x = region.getUpperX(); x >= region.getLowerX(); x--)
|
||||
{
|
||||
//Three level loop now processes 27 voxel neighbourhood
|
||||
for(int innerZ = -1; innerZ <=1; innerZ++)
|
||||
@ -178,18 +159,9 @@ int32_t testDirectAccessWithWrappingBackwards(const VolumeType* volume, int lowX
|
||||
for(int innerY = -1; innerY <=1; innerY++)
|
||||
{
|
||||
for(int innerX = -1; innerX <=1; innerX++)
|
||||
{
|
||||
// Deeply nested 'if', but this is just a unit test and we should still
|
||||
// see some performance improvement by skipping the wrapping versions.
|
||||
if(bAllVoxelsInternal)
|
||||
{
|
||||
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ, WrapModes::Border, 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//End of inner loops
|
||||
@ -201,7 +173,7 @@ int32_t testDirectAccessWithWrappingBackwards(const VolumeType* volume, int lowX
|
||||
}
|
||||
|
||||
template <typename VolumeType>
|
||||
int32_t testSamplersWithWrappingBackwards(VolumeType* volume, int lowXOffset, int lowYOffset, int lowZOffset, int highXOffset, int highYOffset, int highZOffset)
|
||||
int32_t testSamplersWithWrappingBackwards(VolumeType* volume, Region region)
|
||||
{
|
||||
int32_t result = 0;
|
||||
|
||||
@ -210,18 +182,14 @@ int32_t testSamplersWithWrappingBackwards(VolumeType* volume, int lowXOffset, in
|
||||
typename VolumeType::Sampler ySampler(volume);
|
||||
typename VolumeType::Sampler zSampler(volume);
|
||||
|
||||
xSampler.setWrapMode(WrapModes::Border, 3);
|
||||
ySampler.setWrapMode(WrapModes::Border, 3);
|
||||
zSampler.setWrapMode(WrapModes::Border, 3);
|
||||
|
||||
zSampler.setPosition(volume->getEnclosingRegion().getUpperX() + highXOffset, volume->getEnclosingRegion().getUpperY() + highYOffset, volume->getEnclosingRegion().getUpperZ() + highZOffset);
|
||||
for(int z = volume->getEnclosingRegion().getUpperZ() + highZOffset; z >= volume->getEnclosingRegion().getLowerZ() + lowZOffset; z--)
|
||||
zSampler.setPosition(region.getUpperX(), region.getUpperY(), region.getUpperZ());
|
||||
for (int z = region.getUpperZ(); z >= region.getLowerZ(); z--)
|
||||
{
|
||||
ySampler = zSampler;
|
||||
for(int y = volume->getEnclosingRegion().getUpperY() + highYOffset; y >= volume->getEnclosingRegion().getLowerY() + lowYOffset; y--)
|
||||
for (int y = region.getUpperY(); y >= region.getLowerY(); y--)
|
||||
{
|
||||
xSampler = ySampler;
|
||||
for(int x = volume->getEnclosingRegion().getUpperX() + highXOffset; x >= volume->getEnclosingRegion().getLowerX() + lowXOffset; x--)
|
||||
for (int x = region.getUpperX(); x >= region.getLowerX(); x--)
|
||||
{
|
||||
xSampler.setPosition(x, y, z); // HACK - Accessing a volume through multiple samplers currently breaks the PagedVolume.
|
||||
|
||||
@ -267,26 +235,32 @@ int32_t testSamplersWithWrappingBackwards(VolumeType* volume, int lowXOffset, in
|
||||
|
||||
TestVolume::TestVolume()
|
||||
{
|
||||
Region region(-57, -31, 12, 64, 96, 131); // Deliberatly awkward size
|
||||
m_regVolume = Region(-57, -31, 12, 64, 96, 131); // Deliberatly awkward size
|
||||
|
||||
m_regInternal = m_regVolume;
|
||||
m_regInternal.shiftLowerCorner(4, 2, 2);
|
||||
m_regInternal.shiftUpperCorner(-3, -1, -2);
|
||||
|
||||
m_regExternal = m_regVolume;
|
||||
m_regExternal.shiftLowerCorner(-1, -3, -2);
|
||||
m_regExternal.shiftUpperCorner(2, 5, 4);
|
||||
|
||||
m_pFilePager = new FilePager<int32_t>(".");
|
||||
|
||||
//Create the volumes
|
||||
m_pRawVolume = new RawVolume<int32_t>(region);
|
||||
m_pPagedVolume = new PagedVolume<int32_t>(region, m_pFilePager, 32);
|
||||
|
||||
m_pPagedVolume->setMemoryUsageLimit(1 * 1024 * 1024);
|
||||
m_pRawVolume = new RawVolume<int32_t>(m_regVolume);
|
||||
m_pPagedVolume = new PagedVolume<int32_t>(m_pFilePager, 1 * 1024 * 1024, 32);
|
||||
|
||||
//Fill the volume with some data
|
||||
for(int z = region.getLowerZ(); z <= region.getUpperZ(); z++)
|
||||
for (int z = m_regVolume.getLowerZ(); z <= m_regVolume.getUpperZ(); z++)
|
||||
{
|
||||
for(int y = region.getLowerY(); y <= region.getUpperY(); y++)
|
||||
for (int y = m_regVolume.getLowerY(); y <= m_regVolume.getUpperY(); y++)
|
||||
{
|
||||
for(int x = region.getLowerX(); x <= region.getUpperX(); x++)
|
||||
for (int x = m_regVolume.getLowerX(); x <= m_regVolume.getUpperX(); x++)
|
||||
{
|
||||
int32_t value = x + y + z;
|
||||
m_pRawVolume->setVoxelAt(x, y, z, value);
|
||||
m_pPagedVolume->setVoxelAt(x, y, z, value);
|
||||
m_pRawVolume->setVoxel(x, y, z, value);
|
||||
m_pPagedVolume->setVoxel(x, y, z, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -310,7 +284,7 @@ void TestVolume::testRawVolumeDirectAccessAllInternalForwards()
|
||||
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testDirectAccessWithWrappingForwards(m_pRawVolume, 4, 2, 2, -3, -1, -2);
|
||||
result = testDirectAccessWithWrappingForwards(m_pRawVolume, m_regInternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||
}
|
||||
@ -321,7 +295,7 @@ void TestVolume::testRawVolumeSamplersAllInternalForwards()
|
||||
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testSamplersWithWrappingForwards(m_pRawVolume, 4, 2, 2, -3, -1, -2);
|
||||
result = testSamplersWithWrappingForwards(m_pRawVolume, m_regInternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||
}
|
||||
@ -332,9 +306,9 @@ void TestVolume::testRawVolumeDirectAccessWithExternalForwards()
|
||||
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testDirectAccessWithWrappingForwards(m_pRawVolume, -1, -3, -2, 2, 5, 4);
|
||||
result = testDirectAccessWithWrappingForwards(m_pRawVolume, m_regExternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||
QCOMPARE(result, static_cast<int32_t>(337227750));
|
||||
}
|
||||
|
||||
void TestVolume::testRawVolumeSamplersWithExternalForwards()
|
||||
@ -343,9 +317,9 @@ void TestVolume::testRawVolumeSamplersWithExternalForwards()
|
||||
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testSamplersWithWrappingForwards(m_pRawVolume, -1, -3, -2, 2, 5, 4);
|
||||
result = testSamplersWithWrappingForwards(m_pRawVolume, m_regExternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||
QCOMPARE(result, static_cast<int32_t>(337227750));
|
||||
}
|
||||
|
||||
void TestVolume::testRawVolumeDirectAccessAllInternalBackwards()
|
||||
@ -354,7 +328,7 @@ void TestVolume::testRawVolumeDirectAccessAllInternalBackwards()
|
||||
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testDirectAccessWithWrappingBackwards(m_pRawVolume, 4, 2, 2, -3, -1, -2);
|
||||
result = testDirectAccessWithWrappingBackwards(m_pRawVolume, m_regInternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||
}
|
||||
@ -365,7 +339,7 @@ void TestVolume::testRawVolumeSamplersAllInternalBackwards()
|
||||
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testSamplersWithWrappingBackwards(m_pRawVolume, 4, 2, 2, -3, -1, -2);
|
||||
result = testSamplersWithWrappingBackwards(m_pRawVolume, m_regInternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||
}
|
||||
@ -376,9 +350,9 @@ void TestVolume::testRawVolumeDirectAccessWithExternalBackwards()
|
||||
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testDirectAccessWithWrappingBackwards(m_pRawVolume, -1, -3, -2, 2, 5, 4);
|
||||
result = testDirectAccessWithWrappingBackwards(m_pRawVolume, m_regExternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||
QCOMPARE(result, static_cast<int32_t>(-993539594));
|
||||
}
|
||||
|
||||
void TestVolume::testRawVolumeSamplersWithExternalBackwards()
|
||||
@ -387,9 +361,9 @@ void TestVolume::testRawVolumeSamplersWithExternalBackwards()
|
||||
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testSamplersWithWrappingBackwards(m_pRawVolume, -1, -3, -2, 2, 5, 4);
|
||||
result = testSamplersWithWrappingBackwards(m_pRawVolume, m_regExternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||
QCOMPARE(result, static_cast<int32_t>(-993539594));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -401,7 +375,7 @@ void TestVolume::testPagedVolumeDirectAccessAllInternalForwards()
|
||||
int32_t result = 0;
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testDirectAccessWithWrappingForwards(m_pPagedVolume, 4, 2, 2, -3, -1, -2);
|
||||
result = testDirectAccessWithWrappingForwards(m_pPagedVolume, m_regInternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||
}
|
||||
@ -411,7 +385,7 @@ void TestVolume::testPagedVolumeSamplersAllInternalForwards()
|
||||
int32_t result = 0;
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testSamplersWithWrappingForwards(m_pPagedVolume, 4, 2, 2, -3, -1, -2);
|
||||
result = testSamplersWithWrappingForwards(m_pPagedVolume, m_regInternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||
}
|
||||
@ -421,9 +395,9 @@ void TestVolume::testPagedVolumeDirectAccessWithExternalForwards()
|
||||
int32_t result = 0;
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testDirectAccessWithWrappingForwards(m_pPagedVolume, -1, -3, -2, 2, 5, 4);
|
||||
result = testDirectAccessWithWrappingForwards(m_pPagedVolume, m_regExternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||
QCOMPARE(result, static_cast<int32_t>(337227750));
|
||||
}
|
||||
|
||||
void TestVolume::testPagedVolumeSamplersWithExternalForwards()
|
||||
@ -431,9 +405,9 @@ void TestVolume::testPagedVolumeSamplersWithExternalForwards()
|
||||
int32_t result = 0;
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testSamplersWithWrappingForwards(m_pPagedVolume, -1, -3, -2, 2, 5, 4);
|
||||
result = testSamplersWithWrappingForwards(m_pPagedVolume, m_regExternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||
QCOMPARE(result, static_cast<int32_t>(337227750));
|
||||
}
|
||||
|
||||
void TestVolume::testPagedVolumeDirectAccessAllInternalBackwards()
|
||||
@ -441,7 +415,7 @@ void TestVolume::testPagedVolumeDirectAccessAllInternalBackwards()
|
||||
int32_t result = 0;
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testDirectAccessWithWrappingBackwards(m_pPagedVolume, 4, 2, 2, -3, -1, -2);
|
||||
result = testDirectAccessWithWrappingBackwards(m_pPagedVolume, m_regInternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||
}
|
||||
@ -451,7 +425,7 @@ void TestVolume::testPagedVolumeSamplersAllInternalBackwards()
|
||||
int32_t result = 0;
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testSamplersWithWrappingBackwards(m_pPagedVolume, 4, 2, 2, -3, -1, -2);
|
||||
result = testSamplersWithWrappingBackwards(m_pPagedVolume, m_regInternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||
}
|
||||
@ -461,9 +435,9 @@ void TestVolume::testPagedVolumeDirectAccessWithExternalBackwards()
|
||||
int32_t result = 0;
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testDirectAccessWithWrappingBackwards(m_pPagedVolume, -1, -3, -2, 2, 5, 4);
|
||||
result = testDirectAccessWithWrappingBackwards(m_pPagedVolume, m_regExternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||
QCOMPARE(result, static_cast<int32_t>(-993539594));
|
||||
}
|
||||
|
||||
void TestVolume::testPagedVolumeSamplersWithExternalBackwards()
|
||||
@ -471,9 +445,9 @@ void TestVolume::testPagedVolumeSamplersWithExternalBackwards()
|
||||
int32_t result = 0;
|
||||
QBENCHMARK
|
||||
{
|
||||
result = testSamplersWithWrappingBackwards(m_pPagedVolume, -1, -3, -2, 2, 5, 4);
|
||||
result = testSamplersWithWrappingBackwards(m_pPagedVolume, m_regExternal);
|
||||
}
|
||||
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||
QCOMPARE(result, static_cast<int32_t>(-993539594));
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestVolume)
|
||||
|
@ -25,6 +25,7 @@ freely, subject to the following restrictions:
|
||||
#define __PolyVox_TestVolume_H__
|
||||
|
||||
#include "PolyVox/PolyVoxForwardDeclarations.h"
|
||||
#include "PolyVox/Region.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
@ -56,6 +57,9 @@ private slots:
|
||||
void testPagedVolumeSamplersWithExternalBackwards();
|
||||
|
||||
private:
|
||||
PolyVox::Region m_regVolume;
|
||||
PolyVox::Region m_regInternal;
|
||||
PolyVox::Region m_regExternal;
|
||||
PolyVox::FilePager<int32_t>* m_pFilePager;
|
||||
|
||||
PolyVox::RawVolume<int32_t>* m_pRawVolume;
|
||||
|
Loading…
x
Reference in New Issue
Block a user