Fix Ambient Occlusion Calculator to accept functors, functions and lambdas
By changing the 'pass by value' to be a 'pass by const reference' (and adding some const qualifiers) the calculator can take any of the three types. Performance could be improved further using C++11 perfect forwarding to pass the function on without changing a thing. I added a comment to remind us of this. Also added a test for passing a function and a (commented out) test for passing a lambda.
This commit is contained in:
parent
d6640f64d0
commit
bb87e9e628
@ -49,9 +49,8 @@ namespace PolyVox
|
|||||||
class AmbientOcclusionCalculatorRaycastCallback
|
class AmbientOcclusionCalculatorRaycastCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AmbientOcclusionCalculatorRaycastCallback(IsVoxelTransparentCallback isVoxelTransparentCallback)
|
AmbientOcclusionCalculatorRaycastCallback(IsVoxelTransparentCallback isVoxelTransparentCallback) : mIsVoxelTransparentCallback(isVoxelTransparentCallback)
|
||||||
{
|
{
|
||||||
mIsVoxelTransparentCallback = isVoxelTransparentCallback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const SimpleVolume<uint8_t>::Sampler& sampler)
|
bool operator()(const SimpleVolume<uint8_t>::Sampler& sampler)
|
||||||
@ -65,13 +64,19 @@ namespace PolyVox
|
|||||||
return direct;
|
return direct;
|
||||||
}
|
}
|
||||||
|
|
||||||
IsVoxelTransparentCallback mIsVoxelTransparentCallback;
|
const IsVoxelTransparentCallback& mIsVoxelTransparentCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: The callback needs to be a functor not a function. I haven't been
|
// NOTE: The callback needs to be a functor not a function. I haven't been
|
||||||
// able to work the required template magic to get functions working as well.
|
// able to work the required template magic to get functions working as well.
|
||||||
|
//
|
||||||
|
// Matt: If you make the function take a "IsVoxelTransparentCallback&&" then
|
||||||
|
// it will forward it on. Works for functors, functions and lambdas.
|
||||||
|
// This will be 'perfect forwarding' using 'universal references'
|
||||||
|
// This will require C++11 rvalue references which is why I haven't made the
|
||||||
|
// change yet.
|
||||||
template<typename VolumeType, typename IsVoxelTransparentCallback>
|
template<typename VolumeType, typename IsVoxelTransparentCallback>
|
||||||
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, IsVoxelTransparentCallback isVoxelTransparentCallback);
|
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, const IsVoxelTransparentCallback& isVoxelTransparentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "PolyVoxCore/AmbientOcclusionCalculator.inl"
|
#include "PolyVoxCore/AmbientOcclusionCalculator.inl"
|
||||||
|
@ -24,7 +24,7 @@ freely, subject to the following restrictions:
|
|||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
template<typename VolumeType, typename IsVoxelTransparentCallback>
|
template<typename VolumeType, typename IsVoxelTransparentCallback>
|
||||||
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, IsVoxelTransparentCallback isVoxelTransparentCallback)
|
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, const IsVoxelTransparentCallback& isVoxelTransparentCallback)
|
||||||
{
|
{
|
||||||
typename VolumeType::Sampler m_sampVolume(volInput);
|
typename VolumeType::Sampler m_sampVolume(volInput);
|
||||||
|
|
||||||
|
@ -33,12 +33,17 @@ using namespace PolyVox;
|
|||||||
class IsVoxelTransparent
|
class IsVoxelTransparent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool operator()(uint8_t voxel)
|
bool operator()(uint8_t voxel) const
|
||||||
{
|
{
|
||||||
return voxel == 0;
|
return voxel == 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool isVoxelTransparentFunction(uint8_t voxel)
|
||||||
|
{
|
||||||
|
return voxel == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void TestAmbientOcclusionGenerator::testExecute()
|
void TestAmbientOcclusionGenerator::testExecute()
|
||||||
{
|
{
|
||||||
const int32_t g_uVolumeSideLength = 64;
|
const int32_t g_uVolumeSideLength = 64;
|
||||||
@ -78,6 +83,12 @@ void TestAmbientOcclusionGenerator::testExecute()
|
|||||||
QCOMPARE(static_cast<int>(ambientOcclusionResult[16][16][16]), 103);
|
QCOMPARE(static_cast<int>(ambientOcclusionResult[16][16][16]), 103);
|
||||||
QCOMPARE(static_cast<int>(ambientOcclusionResult[16][24][16]), 123);
|
QCOMPARE(static_cast<int>(ambientOcclusionResult[16][24][16]), 123);
|
||||||
QCOMPARE(static_cast<int>(ambientOcclusionResult[16][31][16]), 173);
|
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);
|
||||||
|
|
||||||
|
//Also test it using a lambda
|
||||||
|
//calculateAmbientOcclusion(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 8, [](uint8_t voxel){return voxel == 0;});
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(TestAmbientOcclusionGenerator)
|
QTEST_MAIN(TestAmbientOcclusionGenerator)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user