calculateAmbientOcclusion() now works with both RawVolume and PagedVolume.

This commit is contained in:
David Williams 2015-03-30 11:44:25 +02:00
parent d000616d3e
commit b415e5c5f3
3 changed files with 20 additions and 13 deletions

View File

@ -45,7 +45,7 @@ namespace PolyVox
* Ambient occlusion
*/
template<typename IsVoxelTransparentCallback>
template<typename VolumeType, typename IsVoxelTransparentCallback>
class AmbientOcclusionCalculatorRaycastCallback
{
public:
@ -53,9 +53,9 @@ namespace PolyVox
{
}
bool operator()(const PagedVolume<uint8_t>::Sampler& sampler)
bool operator()(const typename VolumeType::Sampler& sampler)
{
uint8_t sample = sampler.getVoxel();
auto sample = sampler.getVoxel();
bool func = mIsVoxelTransparentCallback(sample);
return func;
}

View File

@ -35,15 +35,15 @@ namespace PolyVox
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, const Region& region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, IsVoxelTransparentCallback isVoxelTransparentCallback)
{
//Make sure that the size of the volume is an exact multiple of the size of the array.
if(volInput->getWidth() % arrayResult->getDimension(0) != 0)
if (region.getWidthInVoxels() % arrayResult->getDimension(0) != 0)
{
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array width.");
}
if(volInput->getHeight() % arrayResult->getDimension(1) != 0)
if (region.getHeightInVoxels() % arrayResult->getDimension(1) != 0)
{
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array height.");
}
if(volInput->getDepth() % arrayResult->getDimension(2) != 0)
if (region.getDepthInVoxels() % arrayResult->getDimension(2) != 0)
{
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array depth.");
}
@ -61,9 +61,9 @@ namespace PolyVox
//nth 'random' value isn't always followed by the n+1th 'random' value.
uIndexIncreament = 1;
const int iRatioX = volInput->getWidth() / arrayResult->getDimension(0);
const int iRatioY = volInput->getHeight() / arrayResult->getDimension(1);
const int iRatioZ = volInput->getDepth() / arrayResult->getDimension(2);
const int iRatioX = region.getWidthInVoxels() / arrayResult->getDimension(0);
const int iRatioY = region.getHeightInVoxels() / arrayResult->getDimension(1);
const int iRatioZ = region.getDepthInVoxels() / arrayResult->getDimension(2);
const float fRatioX = iRatioX;
const float fRatioY = iRatioY;
@ -104,7 +104,7 @@ namespace PolyVox
Vector3DFloat v3dRayDirection = randomUnitVectors[(uRandomUnitVectorIndex += (++uIndexIncreament)) % 1021]; //Different prime number.
v3dRayDirection *= fRayLength;
AmbientOcclusionCalculatorRaycastCallback<IsVoxelTransparentCallback> ambientOcclusionCalculatorRaycastCallback(isVoxelTransparentCallback);
AmbientOcclusionCalculatorRaycastCallback<VolumeType, IsVoxelTransparentCallback> ambientOcclusionCalculatorRaycastCallback(isVoxelTransparentCallback);
RaycastResult result = raycastWithDirection(volInput, v3dRayStart, v3dRayDirection, ambientOcclusionCalculatorRaycastCallback);
// Note - The performance of this could actually be improved it we exited as soon

View File

@ -24,7 +24,9 @@ freely, subject to the following restrictions:
#include "TestAmbientOcclusionGenerator.h"
#include "PolyVox/AmbientOcclusionCalculator.h"
#include "PolyVox/FilePager.h"
#include "PolyVox/PagedVolume.h"
#include "PolyVox/RawVolume.h"
#include <QtTest>
@ -47,9 +49,14 @@ bool isVoxelTransparentFunction(uint8_t voxel)
void TestAmbientOcclusionGenerator::testExecute()
{
const int32_t g_uVolumeSideLength = 64;
Region region(0, 0, 0, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1);
//Create empty volume
PagedVolume<uint8_t> volData;
RawVolume<uint8_t> volData(region);
// To test with a PagedVolume instead you can comment ou the above line and use these instead.
// FilePager<uint8_t>* pFilePager = new FilePager<uint8_t>(".");
// PagedVolume<uint8_t> volData(pFilePager, 256 * 1024 * 1024, 32);
//Create two solid walls at opposite sides of the volume
for (int32_t z = 0; z < g_uVolumeSideLength; z++)
@ -73,7 +80,7 @@ void TestAmbientOcclusionGenerator::testExecute()
// Calculate the ambient occlusion values
IsVoxelTransparent isVoxelTransparent;
QBENCHMARK {
calculateAmbientOcclusion(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 255, isVoxelTransparent);
calculateAmbientOcclusion(&volData, &ambientOcclusionResult, region, 32.0f, 255, isVoxelTransparent);
}
//Check the results by sampling along a line though the centre of the volume. Because
@ -85,7 +92,7 @@ void TestAmbientOcclusionGenerator::testExecute()
QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 31, 16)), 173);
//Just run a quick test to make sure that it compiles when taking a function pointer
calculateAmbientOcclusion(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 8, &isVoxelTransparentFunction);
calculateAmbientOcclusion(&volData, &ambientOcclusionResult, region, 32.0f, 8, &isVoxelTransparentFunction);
//Also test it using a lambda
//calculateAmbientOcclusion(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 8, [](uint8_t voxel){return voxel == 0;});