517 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			517 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*******************************************************************************
 | |
| Copyright (c) 2010 Matt Williams
 | |
| 
 | |
| This software is provided 'as-is', without any express or implied
 | |
| warranty. In no event will the authors be held liable for any damages
 | |
| arising from the use of this software.
 | |
| 
 | |
| Permission is granted to anyone to use this software for any purpose,
 | |
| including commercial applications, and to alter it and redistribute it
 | |
| freely, subject to the following restrictions:
 | |
| 
 | |
|     1. The origin of this software must not be misrepresented; you must not
 | |
|     claim that you wrote the original software. If you use this software
 | |
|     in a product, an acknowledgment in the product documentation would be
 | |
|     appreciated but is not required.
 | |
| 
 | |
|     2. Altered source versions must be plainly marked as such, and must not be
 | |
|     misrepresented as being the original software.
 | |
| 
 | |
|     3. This notice may not be removed or altered from any source
 | |
|     distribution.
 | |
| *******************************************************************************/
 | |
| 
 | |
| #include "testvolume.h"
 | |
| 
 | |
| #include "PolyVox/FilePager.h"
 | |
| #include "PolyVox/PagedVolume.h"
 | |
| #include "PolyVox/RawVolume.h"
 | |
| 
 | |
| #include <QtGlobal>
 | |
| #include <QtTest>
 | |
| 
 | |
| #include <random>
 | |
| 
 | |
| using namespace PolyVox;
 | |
| 
 | |
| // This is used to compute a value from a list of integers. We use it to 
 | |
| // make sure we get the expected result from a series of volume accesses.
 | |
| inline int32_t cantorTupleFunction(int32_t previousResult, int32_t value)
 | |
| {
 | |
| 	return (( previousResult + value  ) * ( previousResult + value + 1 ) + value ) / 2;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Funtions for testing iteration in a forwards direction
 | |
|  */
 | |
| 
 | |
| // 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, Region region)
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	for (int z = region.getLowerZ(); z <= region.getUpperZ(); z++)
 | |
| 	{
 | |
| 		for (int y = region.getLowerY(); y <= region.getUpperY(); y++)
 | |
| 		{
 | |
| 			for (int x = region.getLowerX(); x <= region.getUpperX(); x++)
 | |
| 			{
 | |
| 				//Three level loop now processes 27 voxel neighbourhood
 | |
| 				for(int innerZ = -1; innerZ <=1; innerZ++)
 | |
| 				{
 | |
| 					for(int innerY = -1; innerY <=1; innerY++)
 | |
| 					{
 | |
| 						for(int innerX = -1; innerX <=1; innerX++)
 | |
| 						{
 | |
| 							result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ));
 | |
| 						}
 | |
| 					}
 | |
| 				}	
 | |
| 				//End of inner loops
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| template <typename VolumeType>
 | |
| int32_t testSamplersWithWrappingForwards(VolumeType* volume, Region region)
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	//Test the sampler move functions
 | |
| 	typename VolumeType::Sampler xSampler(volume);
 | |
| 	typename VolumeType::Sampler ySampler(volume);
 | |
| 	typename VolumeType::Sampler zSampler(volume);
 | |
| 
 | |
| 	zSampler.setPosition(region.getLowerX(), region.getLowerY(), region.getLowerZ());
 | |
| 	for (int z = region.getLowerZ(); z <= region.getUpperZ(); z++)
 | |
| 	{
 | |
| 		ySampler = zSampler;
 | |
| 		for (int y = region.getLowerY(); y <= region.getUpperY(); y++)
 | |
| 		{
 | |
| 			xSampler = ySampler;
 | |
| 			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.
 | |
| 
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px0py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px0py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1py1nz());
 | |
| 
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px0py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px0py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1py0pz());
 | |
| 
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px0py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px0py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1py1pz());
 | |
| 
 | |
| 				xSampler.movePositiveX();
 | |
| 			}
 | |
| 			ySampler.movePositiveY();
 | |
| 		}
 | |
| 		zSampler.movePositiveZ();
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Funtions for testing iteration in a backwards direction
 | |
|  */
 | |
| 
 | |
| // 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, Region region)
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	for (int z = region.getUpperZ(); z >= region.getLowerZ(); z--)
 | |
| 	{
 | |
| 		for (int y = region.getUpperY(); y >= region.getLowerY(); y--)
 | |
| 		{
 | |
| 			for (int x = region.getUpperX(); x >= region.getLowerX(); x--)
 | |
| 			{
 | |
| 				//Three level loop now processes 27 voxel neighbourhood
 | |
| 				for(int innerZ = -1; innerZ <=1; innerZ++)
 | |
| 				{
 | |
| 					for(int innerY = -1; innerY <=1; innerY++)
 | |
| 					{
 | |
| 						for(int innerX = -1; innerX <=1; innerX++)
 | |
| 						{
 | |
| 							result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ));
 | |
| 						}
 | |
| 					}
 | |
| 				}	
 | |
| 				//End of inner loops
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| template <typename VolumeType>
 | |
| int32_t testSamplersWithWrappingBackwards(VolumeType* volume, Region region)
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	//Test the sampler move functions
 | |
| 	typename VolumeType::Sampler xSampler(volume);
 | |
| 	typename VolumeType::Sampler ySampler(volume);
 | |
| 	typename VolumeType::Sampler zSampler(volume);
 | |
| 
 | |
| 	zSampler.setPosition(region.getUpperX(), region.getUpperY(), region.getUpperZ());
 | |
| 	for (int z = region.getUpperZ(); z >= region.getLowerZ(); z--)
 | |
| 	{
 | |
| 		ySampler = zSampler;
 | |
| 		for (int y = region.getUpperY(); y >= region.getLowerY(); y--)
 | |
| 		{
 | |
| 			xSampler = ySampler;
 | |
| 			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.
 | |
| 
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px0py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px0py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1py1nz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1py1nz());
 | |
| 
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px0py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px0py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1py0pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1py0pz());
 | |
| 
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px0py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px0py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel0px1py1pz());
 | |
| 				result = cantorTupleFunction(result, xSampler.peekVoxel1px1py1pz());
 | |
| 
 | |
| 				xSampler.moveNegativeX();
 | |
| 			}
 | |
| 			ySampler.moveNegativeY();
 | |
| 		}
 | |
| 		zSampler.moveNegativeZ();
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| TestVolume::TestVolume()
 | |
| {
 | |
| 	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>(m_regVolume);
 | |
| 	m_pPagedVolume = new PagedVolume<int32_t>(m_pFilePager, 1 * 1024 * 1024, m_uChunkSideLength);
 | |
| 
 | |
| 	//Fill the volume with some data
 | |
| 	for (int z = m_regVolume.getLowerZ(); z <= m_regVolume.getUpperZ(); z++)
 | |
| 	{
 | |
| 		for (int y = m_regVolume.getLowerY(); y <= m_regVolume.getUpperY(); y++)
 | |
| 		{
 | |
| 			for (int x = m_regVolume.getLowerX(); x <= m_regVolume.getUpperX(); x++)
 | |
| 			{
 | |
| 				int32_t value = x + y + z;
 | |
| 				m_pRawVolume->setVoxel(x, y, z, value);
 | |
| 				m_pPagedVolume->setVoxel(x, y, z, value);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Note - We are reusing the FilePager for testing... watch out for conflicts with the main volume.
 | |
| 	m_pPagedVolumeChunk = new PagedVolume<int32_t>::Chunk(Vector3DInt32(10000, 10000, 10000), m_uChunkSideLength, m_pFilePager);
 | |
| 	int32_t i = 0;
 | |
| 	for (uint16_t z = 0; z < m_uChunkSideLength; z++)
 | |
| 	{
 | |
| 		for (uint16_t y = 0; y < m_uChunkSideLength; y++)
 | |
| 		{
 | |
| 			for (uint16_t x = 0; x < m_uChunkSideLength; x++)
 | |
| 			{
 | |
| 				m_pPagedVolumeChunk->setVoxel(x, y, z, ++i);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| TestVolume::~TestVolume()
 | |
| {
 | |
| 	delete m_pPagedVolumeChunk;
 | |
| 
 | |
| 	delete m_pRawVolume;
 | |
| 	delete m_pPagedVolume;
 | |
| 
 | |
| 	delete m_pFilePager;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * RawVolume Tests
 | |
|  */
 | |
| 
 | |
| void TestVolume::testRawVolumeDirectAccessAllInternalForwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testDirectAccessWithWrappingForwards(m_pRawVolume, m_regInternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(1004598054));
 | |
| }
 | |
| 
 | |
| void TestVolume::testRawVolumeSamplersAllInternalForwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testSamplersWithWrappingForwards(m_pRawVolume, m_regInternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(1004598054));
 | |
| }
 | |
| 
 | |
| void TestVolume::testRawVolumeDirectAccessWithExternalForwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testDirectAccessWithWrappingForwards(m_pRawVolume, m_regExternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(337227750));
 | |
| }
 | |
| 
 | |
| void TestVolume::testRawVolumeSamplersWithExternalForwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testSamplersWithWrappingForwards(m_pRawVolume, m_regExternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(337227750));
 | |
| }
 | |
| 
 | |
| void TestVolume::testRawVolumeDirectAccessAllInternalBackwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testDirectAccessWithWrappingBackwards(m_pRawVolume, m_regInternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(-269366578));
 | |
| }
 | |
| 
 | |
| void TestVolume::testRawVolumeSamplersAllInternalBackwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testSamplersWithWrappingBackwards(m_pRawVolume, m_regInternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(-269366578));
 | |
| }
 | |
| 
 | |
| void TestVolume::testRawVolumeDirectAccessWithExternalBackwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testDirectAccessWithWrappingBackwards(m_pRawVolume, m_regExternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(-993539594));
 | |
| }
 | |
| 
 | |
| void TestVolume::testRawVolumeSamplersWithExternalBackwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testSamplersWithWrappingBackwards(m_pRawVolume, m_regExternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(-993539594));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * PagedVolume Tests
 | |
|  */
 | |
| 
 | |
| void TestVolume::testPagedVolumeDirectAccessAllInternalForwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testDirectAccessWithWrappingForwards(m_pPagedVolume, m_regInternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(1004598054));
 | |
| }
 | |
| 
 | |
| void TestVolume::testPagedVolumeSamplersAllInternalForwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testSamplersWithWrappingForwards(m_pPagedVolume, m_regInternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(1004598054));
 | |
| }
 | |
| 
 | |
| void TestVolume::testPagedVolumeDirectAccessWithExternalForwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testDirectAccessWithWrappingForwards(m_pPagedVolume, m_regExternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(337227750));
 | |
| }
 | |
| 
 | |
| void TestVolume::testPagedVolumeSamplersWithExternalForwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testSamplersWithWrappingForwards(m_pPagedVolume, m_regExternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(337227750));
 | |
| }
 | |
| 
 | |
| void TestVolume::testPagedVolumeDirectAccessAllInternalBackwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testDirectAccessWithWrappingBackwards(m_pPagedVolume, m_regInternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(-269366578));
 | |
| }
 | |
| 
 | |
| void TestVolume::testPagedVolumeSamplersAllInternalBackwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testSamplersWithWrappingBackwards(m_pPagedVolume, m_regInternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(-269366578));
 | |
| }
 | |
| 
 | |
| void TestVolume::testPagedVolumeDirectAccessWithExternalBackwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testDirectAccessWithWrappingBackwards(m_pPagedVolume, m_regExternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(-993539594));
 | |
| }
 | |
| 
 | |
| void TestVolume::testPagedVolumeSamplersWithExternalBackwards()
 | |
| {
 | |
| 	int32_t result = 0;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		result = testSamplersWithWrappingBackwards(m_pPagedVolume, m_regExternal);
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(-993539594));
 | |
| }
 | |
| 
 | |
| void TestVolume::testPagedVolumeChunkLocalAccess()
 | |
| {
 | |
| 	std::mt19937 rng;
 | |
| 	int32_t result = 0;
 | |
| 	uint16_t x = rng() % m_uChunkSideLength;
 | |
| 	uint16_t y = rng() % m_uChunkSideLength;
 | |
| 	uint16_t z = rng() % m_uChunkSideLength;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		for (uint32_t ct = 0; ct < 1000000; ct++)
 | |
| 		{
 | |
| 			uint16_t xOffset = rng() % 3;
 | |
| 			uint16_t yOffset = rng() % 3;
 | |
| 			uint16_t zOffset = rng() % 3;
 | |
| 			x += xOffset;
 | |
| 			y += yOffset;
 | |
| 			z += zOffset;
 | |
| 			x %= m_uChunkSideLength;
 | |
| 			y %= m_uChunkSideLength;
 | |
| 			z %= m_uChunkSideLength;
 | |
| 			int32_t voxel = m_pPagedVolumeChunk->getVoxel(x, y, z);
 | |
| 			result = cantorTupleFunction(result, voxel);
 | |
| 		}
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(145244783));
 | |
| }
 | |
| 
 | |
| void TestVolume::testPagedVolumeChunkRandomAccess()
 | |
| {
 | |
| 	std::mt19937 rng;
 | |
| 	int32_t result = 0;
 | |
| 	QBENCHMARK
 | |
| 	{
 | |
| 		for (uint32_t ct = 0; ct < 1000000; ct++)
 | |
| 		{
 | |
| 			uint16_t x = rng() % m_uChunkSideLength;
 | |
| 			uint16_t y = rng() % m_uChunkSideLength;
 | |
| 			uint16_t z = rng() % m_uChunkSideLength;
 | |
| 			int32_t voxel = m_pPagedVolumeChunk->getVoxel(x, y, z);
 | |
| 			result = cantorTupleFunction(result, voxel);
 | |
| 		}
 | |
| 	}
 | |
| 	QCOMPARE(result, static_cast<int32_t>(408757678));
 | |
| }
 | |
| 
 | |
| QTEST_MAIN(TestVolume)
 |