Reverted some of ker's changes to bring back the concepts of width, height, and depth.
This commit is contained in:
parent
624a192be4
commit
596dcf507e
@ -58,9 +58,9 @@ void OpenGLWidget::setVolume(PolyVox::Volume<MaterialDensityPair44>* volData)
|
|||||||
//If we have any volume data then generate the new surface patches.
|
//If we have any volume data then generate the new surface patches.
|
||||||
if(m_volData != 0)
|
if(m_volData != 0)
|
||||||
{
|
{
|
||||||
m_uVolumeWidthInRegions = g_uVolumeSideLength / m_uRegionSideLength;
|
m_uVolumeWidthInRegions = volData->getWidth() / m_uRegionSideLength;
|
||||||
m_uVolumeHeightInRegions = g_uVolumeSideLength / m_uRegionSideLength;
|
m_uVolumeHeightInRegions = volData->getHeight() / m_uRegionSideLength;
|
||||||
m_uVolumeDepthInRegions = g_uVolumeSideLength / m_uRegionSideLength;
|
m_uVolumeDepthInRegions = volData->getDepth() / m_uRegionSideLength;
|
||||||
|
|
||||||
//Our volume is broken down into cuboid regions, and we create one mesh for each region.
|
//Our volume is broken down into cuboid regions, and we create one mesh for each region.
|
||||||
//This three-level for loop iterates over each region.
|
//This three-level for loop iterates over each region.
|
||||||
@ -180,9 +180,8 @@ void OpenGLWidget::paintGL()
|
|||||||
glMatrixMode(GL_MODELVIEW); // Select The Model View Matrix
|
glMatrixMode(GL_MODELVIEW); // Select The Model View Matrix
|
||||||
glLoadIdentity(); // Reset The Current Modelview Matrix
|
glLoadIdentity(); // Reset The Current Modelview Matrix
|
||||||
|
|
||||||
float diag_len = sqrtf(static_cast<float>(255 * 255 * 3));
|
|
||||||
//Moves the camera back so we can see the volume
|
//Moves the camera back so we can see the volume
|
||||||
glTranslatef(0.0f, 0.0f, -diag_len);
|
glTranslatef(0.0f, 0.0f, -m_volData->getDiagonalLength());
|
||||||
|
|
||||||
glRotatef(m_xRotation, 1.0f, 0.0f, 0.0f);
|
glRotatef(m_xRotation, 1.0f, 0.0f, 0.0f);
|
||||||
glRotatef(m_yRotation, 0.0f, 1.0f, 0.0f);
|
glRotatef(m_yRotation, 0.0f, 1.0f, 0.0f);
|
||||||
@ -249,8 +248,7 @@ void OpenGLWidget::setupProjectionMatrix(void)
|
|||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
float diag_len = sqrtf(static_cast<float>(255 * 255 * 3));
|
float frustumSize = m_volData->getDiagonalLength() / 2.0f;
|
||||||
float frustumSize = diag_len / 2.0f;
|
|
||||||
float aspect = static_cast<float>(width()) / static_cast<float>(height());
|
float aspect = static_cast<float>(width()) / static_cast<float>(height());
|
||||||
|
|
||||||
glOrtho(frustumSize*aspect, -frustumSize*aspect, frustumSize, -frustumSize, 1.0, 5000);
|
glOrtho(frustumSize*aspect, -frustumSize*aspect, frustumSize, -frustumSize, 1.0, 5000);
|
||||||
|
@ -27,19 +27,17 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
using namespace PolyVox;
|
using namespace PolyVox;
|
||||||
|
|
||||||
const uint16_t g_uVolumeSideLength = 128;
|
|
||||||
|
|
||||||
void createSphereInVolume(Volume<MaterialDensityPair44>& volData, float fRadius, uint8_t uValue)
|
void createSphereInVolume(Volume<MaterialDensityPair44>& volData, float fRadius, uint8_t uValue)
|
||||||
{
|
{
|
||||||
//This vector hold the position of the center of the volume
|
//This vector hold the position of the center of the volume
|
||||||
Vector3DFloat v3dVolCenter( g_uVolumeSideLength / 2, g_uVolumeSideLength / 2, g_uVolumeSideLength / 2);
|
Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2);
|
||||||
|
|
||||||
//This three-level for loop iterates over every voxel in the volume
|
//This three-level for loop iterates over every voxel in the volume
|
||||||
for (int z = 0; z < g_uVolumeSideLength ; z++)
|
for (int z = 0; z < volData.getWidth(); z++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < g_uVolumeSideLength; y++)
|
for (int y = 0; y < volData.getHeight(); y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < g_uVolumeSideLength; x++)
|
for (int x = 0; x < volData.getDepth(); x++)
|
||||||
{
|
{
|
||||||
//Store our current position as a vector...
|
//Store our current position as a vector...
|
||||||
Vector3DFloat v3dCurrentPos(x,y,z);
|
Vector3DFloat v3dCurrentPos(x,y,z);
|
||||||
|
@ -72,7 +72,7 @@ void exampleLog(string message, int severity)
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
logHandler = &exampleLog;
|
logHandler = &exampleLog;
|
||||||
Volume<MaterialDensityPair44> volData;
|
Volume<MaterialDensityPair44> volData(g_uVolumeSideLength, g_uVolumeSideLength, g_uVolumeSideLength);
|
||||||
|
|
||||||
//Make our volume contain a sphere in the center.
|
//Make our volume contain a sphere in the center.
|
||||||
int32_t minPos = 0;
|
int32_t minPos = 0;
|
||||||
|
@ -44,6 +44,7 @@ namespace PolyVox
|
|||||||
|
|
||||||
void setLowerCorner(const Vector3DInt32& v3dLowerCorner);
|
void setLowerCorner(const Vector3DInt32& v3dLowerCorner);
|
||||||
void setUpperCorner(const Vector3DInt32& v3dUpperCorner);
|
void setUpperCorner(const Vector3DInt32& v3dUpperCorner);
|
||||||
|
void setToMaxSize(void);
|
||||||
|
|
||||||
bool containsPoint(const Vector3DFloat& pos, float boundary = 0.0f) const;
|
bool containsPoint(const Vector3DFloat& pos, float boundary = 0.0f) const;
|
||||||
bool containsPoint(const Vector3DInt32& pos, uint8_t boundary = 0) const;
|
bool containsPoint(const Vector3DInt32& pos, uint8_t boundary = 0) const;
|
||||||
|
@ -32,7 +32,6 @@ freely, subject to the following restrictions:
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
@ -124,9 +123,27 @@ namespace PolyVox
|
|||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Volume(uint16_t uBlockSideLength = 32);
|
Volume(uint16_t uBlockSideLength = 32);
|
||||||
|
/// Constructor
|
||||||
|
Volume(int32_t uWidth, int32_t uHeight, int32_t uDepth, uint16_t uBlockSideLength = 32);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Volume();
|
~Volume();
|
||||||
|
|
||||||
|
/// Gets the value used for voxels which are outside the volume
|
||||||
|
VoxelType getBorderValue(void) const;
|
||||||
|
/// Gets a Region representing the extents of the Volume.
|
||||||
|
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 by <tt>x,y,z</tt> position
|
/// Gets a voxel by <tt>x,y,z</tt> position
|
||||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||||
/// Gets a voxel by 3D vector position
|
/// Gets a voxel by 3D vector position
|
||||||
@ -148,6 +165,7 @@ namespace PolyVox
|
|||||||
uint32_t calculateSizeInBytes(void);
|
uint32_t calculateSizeInBytes(void);
|
||||||
/// Resizes the volume to the specified dimensions
|
/// Resizes the volume to the specified dimensions
|
||||||
void resize(uint16_t uBlockSideLength = 32);
|
void resize(uint16_t uBlockSideLength = 32);
|
||||||
|
void resize(int32_t uWidth, int32_t uHeight, int32_t uDepth, uint16_t uBlockSideLength);
|
||||||
/// gets called when a new region is allocated and needs to be filled
|
/// gets called when a new region is allocated and needs to be filled
|
||||||
/// NOTE: accessing ANY voxels outside this region during the process of this function
|
/// NOTE: accessing ANY voxels outside this region during the process of this function
|
||||||
/// is absolutely unsafe
|
/// is absolutely unsafe
|
||||||
@ -184,8 +202,40 @@ namespace PolyVox
|
|||||||
//the VolumeIterator can do it's usual pointer arithmetic without needing to know it's gone outside the volume.
|
//the VolumeIterator can do it's usual pointer arithmetic without needing to know it's gone outside the volume.
|
||||||
VoxelType* m_pUncompressedBorderData;
|
VoxelType* m_pUncompressedBorderData;
|
||||||
|
|
||||||
|
/*int32_t m_uMinX;
|
||||||
|
int32_t m_uMinY;
|
||||||
|
int32_t m_uMinZ;
|
||||||
|
|
||||||
|
int32_t m_uMaxX;
|
||||||
|
int32_t m_uMaxY;
|
||||||
|
int32_t m_uMaxZ;*/
|
||||||
|
|
||||||
|
Region m_regValidRegion;
|
||||||
|
|
||||||
|
/*int32_t m_uBlockMinX;
|
||||||
|
int32_t m_uBlockMinY;
|
||||||
|
int32_t m_uBlockMinZ;
|
||||||
|
|
||||||
|
int32_t m_uBlockMaxX;
|
||||||
|
int32_t m_uBlockMaxY;
|
||||||
|
int32_t m_uBlockMaxZ;*/
|
||||||
|
|
||||||
|
Region m_regValidRegionInBlocks;
|
||||||
|
|
||||||
|
int32_t m_uWidthInBlocks;
|
||||||
|
int32_t m_uHeightInBlocks;
|
||||||
|
int32_t m_uDepthInBlocks;
|
||||||
|
|
||||||
|
int32_t m_uWidth;
|
||||||
|
int32_t m_uHeight;
|
||||||
|
int32_t m_uDepth;
|
||||||
|
|
||||||
uint8_t m_uBlockSideLengthPower;
|
uint8_t m_uBlockSideLengthPower;
|
||||||
uint16_t m_uBlockSideLength;
|
uint16_t m_uBlockSideLength;
|
||||||
|
|
||||||
|
int32_t m_uLongestSideLength;
|
||||||
|
int32_t m_uShortestSideLength;
|
||||||
|
float m_fDiagonalLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Some handy typedefs
|
//Some handy typedefs
|
||||||
|
@ -59,10 +59,48 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
setBlockCacheSize(m_uMaxUncompressedBlockCacheSize);
|
setBlockCacheSize(m_uMaxUncompressedBlockCacheSize);
|
||||||
|
|
||||||
|
m_regValidRegion.setToMaxSize();
|
||||||
|
|
||||||
|
m_regValidRegionInBlocks.setLowerCorner(m_regValidRegion.getLowerCorner() / static_cast<int32_t>(uBlockSideLength));
|
||||||
|
m_regValidRegionInBlocks.setUpperCorner(m_regValidRegion.getUpperCorner() / static_cast<int32_t>(uBlockSideLength));
|
||||||
|
|
||||||
//Create a volume of the right size.
|
//Create a volume of the right size.
|
||||||
resize(uBlockSideLength);
|
resize(uBlockSideLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Builds a volume of the desired dimensions
|
||||||
|
/// \param uWidth The desired width in voxels. This must be a power of two.
|
||||||
|
/// \param uHeight The desired height in voxels. This must be a power of two.
|
||||||
|
/// \param uDepth The desired depth in voxels. This must be a power of two.
|
||||||
|
/// \param uBlockSideLength The size of the blocks which make up the volume. Small
|
||||||
|
/// blocks are more likely to be homogeneous (so more easily shared) and have better
|
||||||
|
/// cache behaviour. However, there is a memory overhead per block so if they are
|
||||||
|
/// not shared it could actually be less efficient (this will depend on the data).
|
||||||
|
/// The size of the volume may also be a factor when choosing block size. Accept
|
||||||
|
/// the default if you are not sure what to choose here.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename VoxelType>
|
||||||
|
Volume<VoxelType>::Volume(int32_t uWidth, int32_t uHeight, int32_t uDepth, uint16_t uBlockSideLength)
|
||||||
|
:m_uTimestamper(0)
|
||||||
|
,m_uMaxUncompressedBlockCacheSize(256)
|
||||||
|
,m_uBlockSideLength(uBlockSideLength)
|
||||||
|
,m_pUncompressedBorderData(0)
|
||||||
|
,m_uMaxBlocksLoaded(4096)
|
||||||
|
,m_v3dLastAccessedBlockPos((std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)()) //An invalid index
|
||||||
|
{
|
||||||
|
setBlockCacheSize(m_uMaxUncompressedBlockCacheSize);
|
||||||
|
|
||||||
|
m_regValidRegion.setLowerCorner(Vector3DInt32(0,0,0));
|
||||||
|
m_regValidRegion.setUpperCorner(Vector3DInt32(uWidth - 1,uHeight - 1,uDepth - 1));
|
||||||
|
|
||||||
|
m_regValidRegionInBlocks.setLowerCorner(m_regValidRegion.getLowerCorner() / static_cast<int32_t>(uBlockSideLength));
|
||||||
|
m_regValidRegionInBlocks.setUpperCorner(m_regValidRegion.getUpperCorner() / static_cast<int32_t>(uBlockSideLength));
|
||||||
|
|
||||||
|
//Create a volume of the right size.
|
||||||
|
resize(uWidth, uHeight, uDepth, uBlockSideLength);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Destroys the volume and frees any blocks which are not in use by other volumes.
|
/// Destroys the volume and frees any blocks which are not in use by other volumes.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -75,6 +113,95 @@ namespace PolyVox
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// The border value is returned whenever an atempt 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 Volume<VoxelType>::getBorderValue(void) const
|
||||||
|
{
|
||||||
|
/*Block<VoxelType>* pUncompressedBorderBlock = getUncompressedBlock(const_cast<Block<VoxelType>*>(&m_pBorderBlock));
|
||||||
|
return pUncompressedBorderBlock->getVoxelAt(0,0,0);*/
|
||||||
|
return *m_pUncompressedBorderData;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// The result will always have a lower corner at (0,0,0) and an upper corner at one
|
||||||
|
/// less than the side length. For example, if a volume has dimensions 256x512x1024
|
||||||
|
/// then the upper corner of the enclosing region will be at (255,511,1023).
|
||||||
|
/// \return A Region representing the extent of the volume.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename VoxelType>
|
||||||
|
Region Volume<VoxelType>::getEnclosingRegion(void) const
|
||||||
|
{
|
||||||
|
return Region(Vector3DInt32(0,0,0), Vector3DInt32(m_uWidth-1,m_uHeight-1,m_uDepth-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \return The width of the volume in voxels
|
||||||
|
/// \sa getHeight(), getDepth()
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename VoxelType>
|
||||||
|
int32_t Volume<VoxelType>::getWidth(void) const
|
||||||
|
{
|
||||||
|
return m_uWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \return The height of the volume in voxels
|
||||||
|
/// \sa getWidth(), getDepth()
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename VoxelType>
|
||||||
|
int32_t Volume<VoxelType>::getHeight(void) const
|
||||||
|
{
|
||||||
|
return m_uHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \return The depth of the volume in voxels
|
||||||
|
/// \sa getWidth(), getHeight()
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename VoxelType>
|
||||||
|
int32_t Volume<VoxelType>::getDepth(void) const
|
||||||
|
{
|
||||||
|
return m_uDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \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 Volume<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 Volume<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 Volume<VoxelType>::getDiagonalLength(void) const
|
||||||
|
{
|
||||||
|
return m_fDiagonalLength;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// \param uXPos the \c x position of the voxel
|
/// \param uXPos the \c x position of the voxel
|
||||||
/// \param uYPos the \c y position of the voxel
|
/// \param uYPos the \c y position of the voxel
|
||||||
@ -145,6 +272,17 @@ namespace PolyVox
|
|||||||
m_uMaxBlocksLoaded = uMaxBlocks;
|
m_uMaxBlocksLoaded = uMaxBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \param tBorder The value to use for voxels outside the volume.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename VoxelType>
|
||||||
|
void Volume<VoxelType>::setBorderValue(const VoxelType& tBorder)
|
||||||
|
{
|
||||||
|
/*Block<VoxelType>* pUncompressedBorderBlock = getUncompressedBlock(&m_pBorderBlock);
|
||||||
|
return pUncompressedBorderBlock->fill(tBorder);*/
|
||||||
|
std::fill(m_pUncompressedBorderData, m_pUncompressedBorderData + m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength, tBorder);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// \param uXPos the \c x position of the voxel
|
/// \param uXPos the \c x position of the voxel
|
||||||
/// \param uYPos the \c y position of the voxel
|
/// \param uYPos the \c y position of the voxel
|
||||||
@ -230,6 +368,99 @@ namespace PolyVox
|
|||||||
m_uBlockSideLengthPower = logBase2(m_uBlockSideLength);
|
m_uBlockSideLengthPower = logBase2(m_uBlockSideLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Note: Calling this function will destroy all existing data in the volume.
|
||||||
|
/// \param uWidth The desired width in voxels. This must be a power of two.
|
||||||
|
/// \param uHeight The desired height in voxels. This must be a power of two.
|
||||||
|
/// \param uDepth The desired depth in voxels. This must be a power of two.
|
||||||
|
/// \param uBlockSideLength The size of the blocks which make up the volume. Small
|
||||||
|
/// blocks are more likely to be homogeneous (so more easily shared) and have better
|
||||||
|
/// cache behaviour. However, there is a memory overhead per block so if they are
|
||||||
|
/// not shared it could actually be less efficient (this will depend on the data).
|
||||||
|
/// The size of the volume may also be a factor when choosing block size. Accept
|
||||||
|
/// the default if you are not sure what to choose here.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename VoxelType>
|
||||||
|
void Volume<VoxelType>::resize(int32_t uWidth, int32_t uHeight, int32_t uDepth, uint16_t uBlockSideLength)
|
||||||
|
{
|
||||||
|
//Debug mode validation
|
||||||
|
assert(uBlockSideLength > 0);
|
||||||
|
assert(isPowerOf2(uBlockSideLength));
|
||||||
|
assert(uBlockSideLength <= uWidth);
|
||||||
|
assert(uBlockSideLength <= uHeight);
|
||||||
|
assert(uBlockSideLength <= uDepth);
|
||||||
|
assert(0 < uWidth);
|
||||||
|
assert(0 < uHeight);
|
||||||
|
assert(0 < uDepth);
|
||||||
|
|
||||||
|
//Release mode validation
|
||||||
|
if(uBlockSideLength == 0)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Block side length cannot be zero.");
|
||||||
|
}
|
||||||
|
if(!isPowerOf2(uBlockSideLength))
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Block side length must be a power of two.");
|
||||||
|
}
|
||||||
|
if(uBlockSideLength > uWidth)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Block side length cannot be greater than volume width.");
|
||||||
|
}
|
||||||
|
if(uBlockSideLength > uHeight)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Block side length cannot be greater than volume height.");
|
||||||
|
}
|
||||||
|
if(uBlockSideLength > uDepth)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Block side length cannot be greater than volume depth.");
|
||||||
|
}
|
||||||
|
if(0 >= uWidth)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Volume width cannot be smaller than 1.");
|
||||||
|
}
|
||||||
|
if(0 >= uHeight)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Volume height cannot be smaller than 1.");
|
||||||
|
}
|
||||||
|
if(0 >= uDepth)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Volume depth cannot be smaller than 1.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Clear the previous data
|
||||||
|
m_pBlocks.clear();
|
||||||
|
m_pUncompressedTimestamps.clear();
|
||||||
|
|
||||||
|
//Compute the volume side lengths
|
||||||
|
m_uWidth = uWidth;
|
||||||
|
m_uHeight = uHeight;
|
||||||
|
m_uDepth = uDepth;
|
||||||
|
|
||||||
|
//Compute the block side length
|
||||||
|
m_uBlockSideLength = uBlockSideLength;
|
||||||
|
m_uBlockSideLengthPower = logBase2(m_uBlockSideLength);
|
||||||
|
|
||||||
|
//Compute the side lengths in blocks
|
||||||
|
m_uWidthInBlocks = m_uWidth / m_uBlockSideLength;
|
||||||
|
m_uHeightInBlocks = m_uHeight / m_uBlockSideLength;
|
||||||
|
m_uDepthInBlocks = m_uDepth / m_uBlockSideLength;
|
||||||
|
|
||||||
|
//Clear the previous data
|
||||||
|
m_pBlocks.clear();
|
||||||
|
m_pUncompressedTimestamps.clear();
|
||||||
|
|
||||||
|
m_pUncompressedTimestamps.resize(m_uMaxUncompressedBlockCacheSize, 0);
|
||||||
|
|
||||||
|
//Create the border block
|
||||||
|
m_pUncompressedBorderData = new VoxelType[m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength];
|
||||||
|
std::fill(m_pUncompressedBorderData, m_pUncompressedBorderData + m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength, VoxelType());
|
||||||
|
|
||||||
|
//Other properties we might find useful later
|
||||||
|
m_uLongestSideLength = (std::max)((std::max)(m_uWidth,m_uHeight),m_uDepth);
|
||||||
|
m_uShortestSideLength = (std::min)((std::min)(m_uWidth,m_uHeight),m_uDepth);
|
||||||
|
m_fDiagonalLength = sqrtf(static_cast<float>(m_uWidth * m_uWidth + m_uHeight * m_uHeight + m_uDepth * m_uDepth));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Volume<VoxelType>::eraseBlock(typename std::map<Vector3DInt32, Block<VoxelType> >::iterator itBlock) const
|
void Volume<VoxelType>::eraseBlock(typename std::map<Vector3DInt32, Block<VoxelType> >::iterator itBlock) const
|
||||||
{
|
{
|
||||||
|
@ -153,9 +153,23 @@ namespace PolyVox
|
|||||||
uYPosInBlock * mVolume->m_uBlockSideLength +
|
uYPosInBlock * mVolume->m_uBlockSideLength +
|
||||||
uZPosInBlock * mVolume->m_uBlockSideLength * mVolume->m_uBlockSideLength;
|
uZPosInBlock * mVolume->m_uBlockSideLength * mVolume->m_uBlockSideLength;
|
||||||
|
|
||||||
Block<VoxelType>* pUncompressedCurrentBlock = mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock);
|
//if((uXBlock < mVolume->m_uWidthInBlocks) && (uYBlock < mVolume->m_uHeightInBlocks) && (uZBlock < mVolume->m_uDepthInBlocks) && (uXBlock >= 0) && (uYBlock >= 0) && (uZBlock >=0))
|
||||||
|
//if((uXBlock <= mVolume->m_uBlockMaxX) && (uYBlock <= mVolume->m_uBlockMaxY) && (uZBlock <= mVolume->m_uBlockMaxZ) && (uXBlock >= mVolume->m_uBlockMinX) && (uYBlock >= mVolume->m_uBlockMinY) && (uZBlock >= mVolume->m_uBlockMinZ))
|
||||||
|
if(mVolume->m_regValidRegionInBlocks.containsPoint(Vector3DInt32(uXBlock, uYBlock, uZBlock)))
|
||||||
|
{
|
||||||
|
/*const uint32_t uBlockIndexInVolume = uXBlock +
|
||||||
|
uYBlock * mVolume->m_uWidthInBlocks +
|
||||||
|
uZBlock * mVolume->m_uWidthInBlocks * mVolume->m_uHeightInBlocks;
|
||||||
|
const Block<VoxelType>& currentBlock = mVolume->m_pBlocks[uBlockIndexInVolume];*/
|
||||||
|
|
||||||
mCurrentVoxel = pUncompressedCurrentBlock->m_tUncompressedData + uVoxelIndexInBlock;
|
Block<VoxelType>* pUncompressedCurrentBlock = mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock);
|
||||||
|
|
||||||
|
mCurrentVoxel = pUncompressedCurrentBlock->m_tUncompressedData + uVoxelIndexInBlock;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mCurrentVoxel = mVolume->m_pUncompressedBorderData + uVoxelIndexInBlock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
|
@ -41,15 +41,22 @@ namespace PolyVox
|
|||||||
|
|
||||||
VolumeSampler<uint8_t> volIter(volumeData);
|
VolumeSampler<uint8_t> volIter(volumeData);
|
||||||
|
|
||||||
Vector3DFloat v3dGradient = computeNormal(volumeData, v3dPos, normalGenerationMethod);
|
//Check all corners are within the volume, allowing a boundary for gradient estimation
|
||||||
|
bool lowerCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor,2);
|
||||||
|
bool upperCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor+Vector3DInt32(1,1,1),2);
|
||||||
|
|
||||||
if(v3dGradient.lengthSquared() > 0.0001)
|
if(lowerCornerInside && upperCornerInside) //If this test fails the vertex will be left as it was
|
||||||
{
|
{
|
||||||
//If we got a normal of significant length then update it.
|
Vector3DFloat v3dGradient = computeNormal(volumeData, v3dPos, normalGenerationMethod);
|
||||||
//Otherwise leave it as it was (should be the 'simple' version)
|
|
||||||
v3dGradient.normalise();
|
if(v3dGradient.lengthSquared() > 0.0001)
|
||||||
iterSurfaceVertex->setNormal(v3dGradient);
|
{
|
||||||
}
|
//If we got a normal of significant length then update it.
|
||||||
|
//Otherwise leave it as it was (should be the 'simple' version)
|
||||||
|
v3dGradient.normalise();
|
||||||
|
iterSurfaceVertex->setNormal(v3dGradient);
|
||||||
|
}
|
||||||
|
} //(lowerCornerInside && upperCornerInside)
|
||||||
++iterSurfaceVertex;
|
++iterSurfaceVertex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,14 @@ namespace PolyVox
|
|||||||
m_v3dUpperCorner = v3dUpperCorner;
|
m_v3dUpperCorner = v3dUpperCorner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Region::setToMaxSize(void)
|
||||||
|
{
|
||||||
|
int32_t iMin = (std::numeric_limits<int32_t>::min)();
|
||||||
|
int32_t iMax = (std::numeric_limits<int32_t>::max)();
|
||||||
|
m_v3dLowerCorner = Vector3DInt32(iMin, iMin,iMin);
|
||||||
|
m_v3dUpperCorner = Vector3DInt32(iMax, iMax,iMax);
|
||||||
|
}
|
||||||
|
|
||||||
bool Region::containsPoint(const Vector3DFloat& pos, float boundary) const
|
bool Region::containsPoint(const Vector3DFloat& pos, float boundary) const
|
||||||
{
|
{
|
||||||
return (pos.getX() <= m_v3dUpperCorner.getX() - boundary)
|
return (pos.getX() <= m_v3dUpperCorner.getX() - boundary)
|
||||||
|
@ -29,6 +29,13 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
float computeSmoothedVoxel(VolumeSampler<uint8_t>& volIter)
|
float computeSmoothedVoxel(VolumeSampler<uint8_t>& volIter)
|
||||||
{
|
{
|
||||||
|
assert(volIter.getPosX() >= 1);
|
||||||
|
assert(volIter.getPosY() >= 1);
|
||||||
|
assert(volIter.getPosZ() >= 1);
|
||||||
|
assert(volIter.getPosX() <= volIter.getVolume()->getWidth() - 2);
|
||||||
|
assert(volIter.getPosY() <= volIter.getVolume()->getHeight() - 2);
|
||||||
|
assert(volIter.getPosZ() <= volIter.getVolume()->getDepth() - 2);
|
||||||
|
|
||||||
float sum = 0.0;
|
float sum = 0.0;
|
||||||
|
|
||||||
if(volIter.peekVoxel1nx1ny1nz() != 0) sum += 1.0f;
|
if(volIter.peekVoxel1nx1ny1nz() != 0) sum += 1.0f;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user