diff --git a/examples/OpenGL/Shapes.cpp b/examples/OpenGL/Shapes.cpp index 71449db2..f26a5e16 100644 --- a/examples/OpenGL/Shapes.cpp +++ b/examples/OpenGL/Shapes.cpp @@ -5,14 +5,14 @@ using namespace PolyVox; void createSphereInVolume(Volume& volData, float fRadius, PolyVox::uint8_t uValue) { //This vector hold the position of the center of the volume - Vector3DFloat v3dVolCenter(volData.getSideLength() / 2, volData.getSideLength() / 2, volData.getSideLength() / 2); + Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2); //This three-level for loop iterates over every voxel in the volume - for (int z = 0; z < volData.getSideLength(); z++) + for (int z = 0; z < volData.getWidth(); z++) { - for (int y = 0; y < volData.getSideLength(); y++) + for (int y = 0; y < volData.getHeight(); y++) { - for (int x = 0; x < volData.getSideLength(); x++) + for (int x = 0; x < volData.getDepth(); x++) { //Store our current position as a vector... Vector3DFloat v3dCurrentPos(x,y,z); diff --git a/examples/OpenGL/main.cpp b/examples/OpenGL/main.cpp index 66eb5254..926681ad 100644 --- a/examples/OpenGL/main.cpp +++ b/examples/OpenGL/main.cpp @@ -47,12 +47,12 @@ void exampleLog(string message, int severity) int main(int argc, char *argv[]) { logHandler = &exampleLog; - Volume volData(g_uVolumeSideLength); + Volume volData(g_uVolumeSideLength, g_uVolumeSideLength, g_uVolumeSideLength); //Make our volume contain a sphere in the center. PolyVox::uint16_t minPos = 0; - PolyVox::uint16_t midPos = volData.getSideLength() / 2; - PolyVox::uint16_t maxPos = volData.getSideLength() - 1; + PolyVox::uint16_t midPos = g_uVolumeSideLength / 2; + PolyVox::uint16_t maxPos = g_uVolumeSideLength - 1; createCubeInVolume(volData, Vector3DUint16(minPos, minPos, minPos), Vector3DUint16(maxPos, maxPos, maxPos), 0); createSphereInVolume(volData, 50.0f, 5); diff --git a/library/PolyVoxCore/include/Volume.h b/library/PolyVoxCore/include/Volume.h index 14bd003f..17d9391a 100644 --- a/library/PolyVoxCore/include/Volume.h +++ b/library/PolyVoxCore/include/Volume.h @@ -43,14 +43,19 @@ namespace PolyVox friend class VolumeIterator; public: - Volume(uint16_t uSideLength, uint16_t uBlockSideLength = 64); + Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 64); //Volume(const Volume& rhs); ~Volume(); //Volume& operator=(const Volume& rhs); Region getEnclosingRegion(void) const; - uint16_t getSideLength(void) const; + //uint16_t getSideLength(void) const; + uint16_t getWidth(void) const; + uint16_t getHeight(void) const; + uint16_t getDepth(void) const; + uint16_t getLongestSideLength(void) const; + float getDiagonalLength(void) const; VoxelType getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const; VoxelType getVoxelAt(const Vector3DUint16& v3dPos) const; @@ -74,10 +79,23 @@ namespace PolyVox static std::map > > m_pHomogenousBlockData; uint32_t m_uNoOfBlocksInVolume; - uint16_t m_uSideLengthInBlocks; - uint8_t m_uSideLengthPower; - uint16_t m_uSideLength; + //uint16_t m_uSideLengthInBlocks; + uint16_t m_uWidthInBlocks; + uint16_t m_uHeightInBlocks; + uint16_t m_uDepthInBlocks; + + //uint8_t m_uSideLengthPower; + //uint16_t m_uSideLength; + + uint16_t m_uWidth; + uint8_t m_uWidthPower; + + uint16_t m_uHeight; + uint8_t m_uHeightPower; + + uint16_t m_uDepth; + uint8_t m_uDepthPower; uint8_t m_uBlockSideLengthPower; uint16_t m_uBlockSideLength; diff --git a/library/PolyVoxCore/include/Volume.inl b/library/PolyVoxCore/include/Volume.inl index 1523f09e..469981a1 100644 --- a/library/PolyVoxCore/include/Volume.inl +++ b/library/PolyVoxCore/include/Volume.inl @@ -36,42 +36,63 @@ namespace PolyVox { #pragma region Constructors/Destructors template - Volume::Volume(uint16_t uSideLength, uint16_t uBlockSideLength) + Volume::Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength) :m_pBlocks(0) ,m_uCurrentBlockForTidying(0) { //Debug mode validation - assert(isPowerOf2(uSideLength)); + assert(isPowerOf2(uWidth)); + assert(isPowerOf2(uHeight)); + assert(isPowerOf2(uDepth)); assert(isPowerOf2(uBlockSideLength)); - assert(uBlockSideLength <= uSideLength); + assert(uBlockSideLength <= uWidth); + assert(uBlockSideLength <= uHeight); + assert(uBlockSideLength <= uDepth); //Release mode validation - if(!isPowerOf2(uSideLength)) + if(!(isPowerOf2(uWidth) && isPowerOf2(uHeight) && isPowerOf2(uDepth))) { - throw std::invalid_argument("Volume side length must be a power of two."); + throw std::invalid_argument("Volume width, height, and depth must all be a power of two."); } if(!isPowerOf2(uBlockSideLength)) { throw std::invalid_argument("Block side length must be a power of two."); } - if(uBlockSideLength > uSideLength) + if(uBlockSideLength > uWidth) { - throw std::invalid_argument("Block side length cannot be greater than volume side length."); + 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."); } - //Compute the volume side length - m_uSideLength = uSideLength; - m_uSideLengthPower = logBase2(m_uSideLength); + //Compute the volume side lengths + m_uWidth = uWidth; + m_uWidthPower = logBase2(m_uWidth); + + m_uHeight = uHeight; + m_uHeightPower = logBase2(m_uHeight); + + m_uDepth = uDepth; + m_uDepthPower = logBase2(m_uDepth); //Compute the block side length m_uBlockSideLength = uBlockSideLength; m_uBlockSideLengthPower = logBase2(m_uBlockSideLength); //Compute the side length in blocks - m_uSideLengthInBlocks = m_uSideLength / m_uBlockSideLength; + //m_uSideLengthInBlocks = m_uSideLength / m_uBlockSideLength; + m_uWidthInBlocks = m_uWidth / m_uBlockSideLength; + m_uHeightInBlocks = m_uHeight / m_uBlockSideLength; + m_uDepthInBlocks = m_uDepth / m_uBlockSideLength; //Compute number of blocks in the volume - m_uNoOfBlocksInVolume = m_uSideLengthInBlocks * m_uSideLengthInBlocks * m_uSideLengthInBlocks; + m_uNoOfBlocksInVolume = m_uWidthInBlocks * m_uHeightInBlocks * m_uDepthInBlocks; //Create the blocks m_pBlocks.resize(m_uNoOfBlocksInVolume); @@ -107,21 +128,45 @@ namespace PolyVox template Region Volume::getEnclosingRegion(void) const { - return Region(Vector3DInt32(0,0,0), Vector3DInt32(m_uSideLength-1,m_uSideLength-1,m_uSideLength-1)); + return Region(Vector3DInt32(0,0,0), Vector3DInt32(m_uWidth-1,m_uHeight-1,m_uDepth-1)); } template - uint16_t Volume::getSideLength(void) const + uint16_t Volume::getDepth(void) const { - return m_uSideLength; + return m_uDepth; } + template + float Volume::getDiagonalLength(void) const + { + return sqrtf(static_cast(m_uWidth * m_uWidth + m_uHeight * m_uHeight + m_uDepth * m_uDepth)); + } + + template + uint16_t Volume::getHeight(void) const + { + return m_uHeight; + } + + template + uint16_t Volume::getLongestSideLength(void) const + { + return (std::max)((std::max)(m_uWidth,m_uHeight),m_uDepth); + } + + template + uint16_t Volume::getWidth(void) const + { + return m_uWidth; + } + template VoxelType Volume::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const { - assert(uXPos < getSideLength()); - assert(uYPos < getSideLength()); - assert(uZPos < getSideLength()); + assert(uXPos < getWidth()); + assert(uYPos < getHeight()); + assert(uZPos < getDepth()); const uint16_t blockX = uXPos >> m_uBlockSideLengthPower; const uint16_t blockY = uYPos >> m_uBlockSideLengthPower; @@ -134,8 +179,8 @@ namespace PolyVox const POLYVOX_SHARED_PTR< BlockData< VoxelType > >& block = m_pBlocks [ blockX + - blockY * m_uSideLengthInBlocks + - blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks + blockY * m_uWidthInBlocks + + blockZ * m_uWidthInBlocks * m_uHeightInBlocks ]; return block->getVoxelAt(xOffset,yOffset,zOffset); @@ -144,9 +189,9 @@ namespace PolyVox template VoxelType Volume::getVoxelAt(const Vector3DUint16& v3dPos) const { - assert(v3dPos.getX() < m_uSideLength); - assert(v3dPos.getY() < m_uSideLength); - assert(v3dPos.getZ() < m_uSideLength); + assert(v3dPos.getX() < m_uWidth); + assert(v3dPos.getY() < m_uHeight); + assert(v3dPos.getZ() < m_uDepth); return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ()); } @@ -166,8 +211,8 @@ namespace PolyVox uint32_t uBlockIndex = blockX + - blockY * m_uSideLengthInBlocks + - blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks; + blockY * m_uWidthInBlocks + + blockZ * m_uWidthInBlocks * m_uHeightInBlocks; POLYVOX_SHARED_PTR< BlockData >& block = m_pBlocks[uBlockIndex]; diff --git a/library/PolyVoxCore/include/VolumeIterator.inl b/library/PolyVoxCore/include/VolumeIterator.inl index 32570129..8316b6f0 100644 --- a/library/PolyVoxCore/include/VolumeIterator.inl +++ b/library/PolyVoxCore/include/VolumeIterator.inl @@ -199,8 +199,8 @@ namespace PolyVox mZPosInBlock = mZPosInVolume - (mZBlock << mVolume.m_uBlockSideLengthPower); mBlockIndexInVolume = mXBlock + - mYBlock * mVolume.m_uSideLengthInBlocks + - mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks; + mYBlock * mVolume.m_uWidthInBlocks + + mZBlock * mVolume.m_uWidthInBlocks * mVolume.m_uHeightInBlocks; POLYVOX_SHARED_PTR< BlockData > currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; mVoxelIndexInBlock = mXPosInBlock + @@ -287,11 +287,11 @@ namespace PolyVox { mXBlock = mXRegionFirstBlock; mBlockIndexInVolume = mXBlock + - mYBlock * mVolume.m_uSideLengthInBlocks + - mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks; + mYBlock * mVolume.m_uWidthInBlocks + + mZBlock * mVolume.m_uWidthInBlocks * mVolume.m_uHeightInBlocks; ++mYBlock; - mBlockIndexInVolume += mVolume.m_uSideLengthInBlocks; + mBlockIndexInVolume += mVolume.m_uWidthInBlocks; if(mYBlock > mYRegionLastBlock) { mYBlock = mYRegionFirstBlock; @@ -300,7 +300,7 @@ namespace PolyVox mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks; ++mZBlock; - mBlockIndexInVolume += mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks; + mBlockIndexInVolume += mVolume.m_uWidthInBlocks * mVolume.m_uHeightInBlocks; if(mZBlock > mZRegionLastBlock) { mIsValidForRegion = false; diff --git a/library/PolyVoxCore/source/VoxelFilters.cpp b/library/PolyVoxCore/source/VoxelFilters.cpp index 1b529ac8..b90e40c4 100644 --- a/library/PolyVoxCore/source/VoxelFilters.cpp +++ b/library/PolyVoxCore/source/VoxelFilters.cpp @@ -9,9 +9,9 @@ namespace PolyVox assert(volIter.getPosX() >= 1); assert(volIter.getPosY() >= 1); assert(volIter.getPosZ() >= 1); - assert(volIter.getPosX() <= volIter.getVolume().getSideLength() - 2); - assert(volIter.getPosY() <= volIter.getVolume().getSideLength() - 2); - assert(volIter.getPosZ() <= volIter.getVolume().getSideLength() - 2); + 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; diff --git a/library/PolyVoxUtil/include/VolumeChangeTracker.h b/library/PolyVoxUtil/include/VolumeChangeTracker.h index de3b45ce..a43e0da1 100644 --- a/library/PolyVoxUtil/include/VolumeChangeTracker.h +++ b/library/PolyVoxUtil/include/VolumeChangeTracker.h @@ -42,7 +42,9 @@ namespace PolyVox int32_t getCurrentTime(void) const; Region getEnclosingRegion(void) const; int32_t getLastModifiedTimeForRegion(uint16_t uX, uint16_t uY, uint16_t uZ); - uint16_t getSideLength(void); + uint16_t getWidth(void); + uint16_t getHeight(void); + uint16_t getDepth(void); Volume* getVolumeData(void) const; uint8_t getVoxelAt(const Vector3DUint16& pos); uint8_t getVoxelAt(uint16_t uX, uint16_t uY, uint16_t uZ); @@ -64,7 +66,9 @@ namespace PolyVox uint16_t m_uRegionSideLength; uint8_t m_uRegionSideLengthPower; - uint16_t m_uVolumeSideLengthInRegions; + uint16_t m_uVolumeWidthInRegions; + uint16_t m_uVolumeHeightInRegions; + uint16_t m_uVolumeDepthInRegions; //It's not what the block class was designed for, but it diff --git a/library/PolyVoxUtil/source/Serialization.cpp b/library/PolyVoxUtil/source/Serialization.cpp index 557cfbb2..073b7dd6 100644 --- a/library/PolyVoxUtil/source/Serialization.cpp +++ b/library/PolyVoxUtil/source/Serialization.cpp @@ -25,7 +25,7 @@ namespace PolyVox uint16_t volumeDepth = 0x0001 << volumeDepthPower; //FIXME - need to support non cubic volumes - Volume* volume = new Volume(volumeWidth); + Volume* volume = new Volume(volumeWidth, volumeHeight, volumeDepth); //Read data for(uint16_t z = 0; z < volumeDepth; ++z) @@ -48,9 +48,9 @@ namespace PolyVox void saveVolumeRaw(std::ostream& stream, Volume& volume) { //Write volume dimensions - uint16_t volumeWidth = volume.getSideLength(); - uint16_t volumeHeight = volume.getSideLength(); - uint16_t volumeDepth = volume.getSideLength(); + uint16_t volumeWidth = volume.getWidth(); + uint16_t volumeHeight = volume.getHeight(); + uint16_t volumeDepth = volume.getDepth(); uint8_t volumeWidthPower = logBase2(volumeWidth); uint8_t volumeHeightPower = logBase2(volumeHeight); @@ -93,7 +93,7 @@ namespace PolyVox uint16_t volumeDepth = 0x0001 << volumeDepthPower; //FIXME - need to support non cubic volumes - Volume* volume = new Volume(volumeWidth); + Volume* volume = new Volume(volumeWidth, volumeHeight, volumeDepth); //Read data bool firstTime = true; @@ -130,9 +130,9 @@ namespace PolyVox void saveVolumeRle(std::ostream& stream, Volume& volume) { //Write volume dimensions - uint16_t volumeWidth = volume.getSideLength(); - uint16_t volumeHeight = volume.getSideLength(); - uint16_t volumeDepth = volume.getSideLength(); + uint16_t volumeWidth = volume.getWidth(); + uint16_t volumeHeight = volume.getHeight(); + uint16_t volumeDepth = volume.getDepth(); uint8_t volumeWidthPower = logBase2(volumeWidth); uint8_t volumeHeightPower = logBase2(volumeHeight); diff --git a/library/PolyVoxUtil/source/VolumeChangeTracker.cpp b/library/PolyVoxUtil/source/VolumeChangeTracker.cpp index 4da5094d..c32934e2 100644 --- a/library/PolyVoxUtil/source/VolumeChangeTracker.cpp +++ b/library/PolyVoxUtil/source/VolumeChangeTracker.cpp @@ -46,10 +46,14 @@ namespace PolyVox ,m_uRegionSideLength(regionSideLength) { volumeData = volumeDataToSet; - m_uVolumeSideLengthInRegions = volumeData->getSideLength() / m_uRegionSideLength; + m_uVolumeWidthInRegions = volumeData->getWidth() / m_uRegionSideLength; + m_uVolumeHeightInRegions = volumeData->getHeight() / m_uRegionSideLength; + m_uVolumeDepthInRegions = volumeData->getDepth() / m_uRegionSideLength; m_uRegionSideLengthPower = PolyVox::logBase2(m_uRegionSideLength); - volRegionLastModified = new BlockData(m_uRegionSideLength); + uint16_t uLongestSideLength = (std::max)((std::max)(m_uVolumeWidthInRegions,m_uVolumeHeightInRegions),m_uVolumeDepthInRegions); + + volRegionLastModified = new BlockData(uLongestSideLength); //FIXME - Maybe using a block here isn't optimal as it must always be cubic... } VolumeChangeTracker::~VolumeChangeTracker() @@ -58,11 +62,11 @@ namespace PolyVox void VolumeChangeTracker::setAllRegionsModified(void) { - for(uint16_t blockZ = 0; blockZ < m_uVolumeSideLengthInRegions; ++blockZ) + for(uint16_t blockZ = 0; blockZ < m_uVolumeDepthInRegions; ++blockZ) { - for(uint16_t blockY = 0; blockY < m_uVolumeSideLengthInRegions; ++blockY) + for(uint16_t blockY = 0; blockY < m_uVolumeHeightInRegions; ++blockY) { - for(uint16_t blockX = 0; blockX < m_uVolumeSideLengthInRegions; ++blockX) + for(uint16_t blockX = 0; blockX < m_uVolumeWidthInRegions; ++blockX) { volRegionLastModified->setVoxelAt(blockX, blockY, blockZ, m_iCurrentTime); ++m_iCurrentTime; @@ -76,9 +80,19 @@ namespace PolyVox return m_iCurrentTime; } - uint16_t VolumeChangeTracker::getSideLength(void) + uint16_t VolumeChangeTracker::getWidth(void) { - return volumeData->getSideLength(); + return volumeData->getWidth(); + } + + uint16_t VolumeChangeTracker::getHeight(void) + { + return volumeData->getHeight(); + } + + uint16_t VolumeChangeTracker::getDepth(void) + { + return volumeData->getDepth(); } Region VolumeChangeTracker::getEnclosingRegion(void) const @@ -98,9 +112,9 @@ namespace PolyVox uint8_t VolumeChangeTracker::getVoxelAt(uint16_t uX, uint16_t uY, uint16_t uZ) { - assert(uX < volumeData->getSideLength()); - assert(uY < volumeData->getSideLength()); - assert(uZ < volumeData->getSideLength()); + assert(uX < volumeData->getWidth()); + assert(uY < volumeData->getHeight()); + assert(uZ < volumeData->getDepth()); VolumeIterator volIter(*volumeData); volIter.setPosition(uX,uY,uZ); @@ -143,9 +157,9 @@ namespace PolyVox const uint16_t minRegionY = (std::max)(uint16_t(0),uint16_t(regionY-1)); const uint16_t minRegionZ = (std::max)(uint16_t(0),uint16_t(regionZ-1)); - const uint16_t maxRegionX = (std::min)(uint16_t(m_uVolumeSideLengthInRegions-1),uint16_t(regionX+1)); - const uint16_t maxRegionY = (std::min)(uint16_t(m_uVolumeSideLengthInRegions-1),uint16_t(regionY+1)); - const uint16_t maxRegionZ = (std::min)(uint16_t(m_uVolumeSideLengthInRegions-1),uint16_t(regionZ+1)); + const uint16_t maxRegionX = (std::min)(uint16_t(m_uVolumeWidthInRegions-1),uint16_t(regionX+1)); + const uint16_t maxRegionY = (std::min)(uint16_t(m_uVolumeHeightInRegions-1),uint16_t(regionY+1)); + const uint16_t maxRegionZ = (std::min)(uint16_t(m_uVolumeDepthInRegions-1),uint16_t(regionZ+1)); for(uint16_t zCt = minRegionZ; zCt <= maxRegionZ; zCt++) {