diff --git a/include/PolyVox/FilePager.h b/include/PolyVox/FilePager.h index 19c8ca62..04eb3b04 100644 --- a/include/PolyVox/FilePager.h +++ b/include/PolyVox/FilePager.h @@ -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()); } } diff --git a/include/PolyVox/PagedVolumeChunk.inl b/include/PolyVox/PagedVolumeChunk.inl index c1bf5c71..5a9a24d3 100644 --- a/include/PolyVox/PagedVolumeChunk.inl +++ b/include/PolyVox/PagedVolumeChunk.inl @@ -41,7 +41,7 @@ namespace PolyVox // Allocate the data const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; - m_tData = new VoxelType[uNoOfVoxels]; + 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) diff --git a/tests/testvolume.cpp b/tests/testvolume.cpp index 1e4d3857..9a7071ac 100644 --- a/tests/testvolume.cpp +++ b/tests/testvolume.cpp @@ -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 -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++) @@ -66,16 +63,7 @@ int32_t testDirectAccessWithWrappingForwards(const VolumeType* volume, int lowXO { 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)); - } + result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ)); } } } @@ -88,7 +76,7 @@ int32_t testDirectAccessWithWrappingForwards(const VolumeType* volume, int lowXO } template -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,14 +85,14 @@ int32_t testSamplersWithWrappingForwards(VolumeType* volume, int lowXOffset, int typename VolumeType::Sampler ySampler(volume); typename VolumeType::Sampler zSampler(volume); - 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. @@ -155,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 -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++) @@ -175,16 +160,7 @@ int32_t testDirectAccessWithWrappingBackwards(const VolumeType* volume, int lowX { 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)); - } + result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ)); } } } @@ -197,7 +173,7 @@ int32_t testDirectAccessWithWrappingBackwards(const VolumeType* volume, int lowX } template -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; @@ -206,14 +182,14 @@ int32_t testSamplersWithWrappingBackwards(VolumeType* volume, int lowXOffset, in typename VolumeType::Sampler ySampler(volume); typename VolumeType::Sampler zSampler(volume); - 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. @@ -259,22 +235,30 @@ 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("."); //Create the volumes - m_pRawVolume = new RawVolume(region); + m_pRawVolume = new RawVolume(m_regVolume); m_pPagedVolume = new PagedVolume(m_pFilePager, 32); m_pPagedVolume->setMemoryUsageLimit(1 * 1024 * 1024); //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->setVoxel(x, y, z, value); @@ -302,7 +286,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(1004598054)); } @@ -313,7 +297,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(1004598054)); } @@ -324,7 +308,7 @@ void TestVolume::testRawVolumeDirectAccessWithExternalForwards() QBENCHMARK { - result = testDirectAccessWithWrappingForwards(m_pRawVolume, -1, -3, -2, 2, 5, 4); + result = testDirectAccessWithWrappingForwards(m_pRawVolume, m_regExternal); } QCOMPARE(result, static_cast(337227750)); } @@ -335,7 +319,7 @@ void TestVolume::testRawVolumeSamplersWithExternalForwards() QBENCHMARK { - result = testSamplersWithWrappingForwards(m_pRawVolume, -1, -3, -2, 2, 5, 4); + result = testSamplersWithWrappingForwards(m_pRawVolume, m_regExternal); } QCOMPARE(result, static_cast(337227750)); } @@ -346,7 +330,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(-269366578)); } @@ -357,7 +341,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(-269366578)); } @@ -368,7 +352,7 @@ void TestVolume::testRawVolumeDirectAccessWithExternalBackwards() QBENCHMARK { - result = testDirectAccessWithWrappingBackwards(m_pRawVolume, -1, -3, -2, 2, 5, 4); + result = testDirectAccessWithWrappingBackwards(m_pRawVolume, m_regExternal); } QCOMPARE(result, static_cast(-993539594)); } @@ -379,7 +363,7 @@ void TestVolume::testRawVolumeSamplersWithExternalBackwards() QBENCHMARK { - result = testSamplersWithWrappingBackwards(m_pRawVolume, -1, -3, -2, 2, 5, 4); + result = testSamplersWithWrappingBackwards(m_pRawVolume, m_regExternal); } QCOMPARE(result, static_cast(-993539594)); } @@ -393,7 +377,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(1004598054)); } @@ -403,7 +387,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(1004598054)); } @@ -413,7 +397,7 @@ 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(337227750)); } @@ -423,7 +407,7 @@ 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(337227750)); } @@ -433,7 +417,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(-269366578)); } @@ -443,7 +427,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(-269366578)); } @@ -453,7 +437,7 @@ 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(-993539594)); } @@ -463,7 +447,7 @@ 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(-993539594)); } diff --git a/tests/testvolume.h b/tests/testvolume.h index 41ec64dd..79bab98d 100644 --- a/tests/testvolume.h +++ b/tests/testvolume.h @@ -25,6 +25,7 @@ freely, subject to the following restrictions: #define __PolyVox_TestVolume_H__ #include "PolyVox/PolyVoxForwardDeclarations.h" +#include "PolyVox/Region.h" #include @@ -56,6 +57,9 @@ private slots: void testPagedVolumeSamplersWithExternalBackwards(); private: + PolyVox::Region m_regVolume; + PolyVox::Region m_regInternal; + PolyVox::Region m_regExternal; PolyVox::FilePager* m_pFilePager; PolyVox::RawVolume* m_pRawVolume;