Improved raycast unit test so that it exits early if the ray leaves the volume.
This commit is contained in:
parent
c37997bfe2
commit
47e8f4a86d
@ -65,6 +65,8 @@ namespace PolyVox
|
||||
Vector3DInt32 getPosition(void) const;
|
||||
inline VoxelType getVoxel(void) const;
|
||||
|
||||
bool isCurrentPositionValid(void) const;
|
||||
|
||||
void setPosition(const Vector3DInt32& v3dNewPos);
|
||||
void setPosition(int32_t xPos, int32_t yPos, int32_t zPos);
|
||||
inline bool setVoxel(VoxelType tValue);
|
||||
@ -110,7 +112,6 @@ namespace PolyVox
|
||||
|
||||
protected:
|
||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
bool isCurrentPositionValid(void) const;
|
||||
|
||||
DerivedVolumeType* mVolume;
|
||||
|
||||
|
@ -60,6 +60,13 @@ namespace PolyVox
|
||||
return mVolume->getVoxelAt(mXPosInVolume, mYPosInVolume, mZPosInVolume);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
bool inline BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::isCurrentPositionValid(void) const
|
||||
{
|
||||
return m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::setPosition(const Vector3DInt32& v3dNewPos)
|
||||
@ -374,11 +381,4 @@ namespace PolyVox
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
bool inline BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::isCurrentPositionValid(void) const
|
||||
{
|
||||
return m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ;
|
||||
}
|
||||
}
|
||||
|
@ -42,18 +42,30 @@ class RaycastTestFunctor
|
||||
{
|
||||
public:
|
||||
RaycastTestFunctor()
|
||||
:m_uTotalVoxelsTouched(0)
|
||||
:m_uVoxelsTouched(0)
|
||||
,m_bRayLeftVolume(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const SimpleVolume<int8_t>::Sampler& sampler)
|
||||
{
|
||||
m_uTotalVoxelsTouched++;
|
||||
m_uVoxelsTouched++;
|
||||
|
||||
// For this particular test we know that we are always starting a ray inside the volume,
|
||||
// so if it ever leaves the volume we know it can't go back in and so we can terminate early.
|
||||
// This optimisation is worthwhile because samplers get slow once outside the volume.
|
||||
if(!sampler.isCurrentPositionValid())
|
||||
{
|
||||
m_bRayLeftVolume = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are in the volume, so decide whether to continue based on the voxel value.
|
||||
return sampler.getVoxel() <= 0;
|
||||
}
|
||||
|
||||
uint32_t m_uTotalVoxelsTouched;
|
||||
uint32_t m_uVoxelsTouched;
|
||||
bool m_bRayLeftVolume;
|
||||
};
|
||||
|
||||
void TestRaycast::testExecute()
|
||||
@ -83,21 +95,23 @@ void TestRaycast::testExecute()
|
||||
//Cast rays from the centre. Roughly 2/3 should escape.
|
||||
Vector3DFloat start (uVolumeSideLength / 2, uVolumeSideLength / 2, uVolumeSideLength / 2);
|
||||
|
||||
// For demonstration purposes we are using the same function object for all raycasts.
|
||||
// Therefore, the state it maintains (total voxels touched) is accumulated over all raycsts.
|
||||
RaycastTestFunctor raycastTestFunctor;
|
||||
|
||||
// We could have counted the total number of hits in the same way as the total number of voxels
|
||||
// touched, but for demonstration and testing purposes we are making use of the raycast return value
|
||||
// and counting them seperatly in this variable.
|
||||
int hits = 0;
|
||||
uint32_t uTotalVoxelsTouched = 0;
|
||||
|
||||
// Cast a large number of random rays
|
||||
for(int ct = 0; ct < 1000000; ct++)
|
||||
{
|
||||
RaycastTestFunctor raycastTestFunctor;
|
||||
RaycastResult result = raycastWithDirection(&volData, start, randomUnitVectors[ct % 1024] * 1000.0f, raycastTestFunctor);
|
||||
|
||||
if(result == RaycastResults::Interupted)
|
||||
uTotalVoxelsTouched += raycastTestFunctor.m_uVoxelsTouched;
|
||||
|
||||
// If the raycast completed then we know it did not hit anything.If it was interupted then it
|
||||
// probably hit something, unless we noted that the reason it was interupted was that it left the volume.
|
||||
if((result == RaycastResults::Interupted) && (raycastTestFunctor.m_bRayLeftVolume == false))
|
||||
{
|
||||
hits++;
|
||||
}
|
||||
@ -107,7 +121,7 @@ void TestRaycast::testExecute()
|
||||
QCOMPARE(hits, 687494);
|
||||
|
||||
// Check the total number of voxels touched
|
||||
QCOMPARE(raycastTestFunctor.m_uTotalVoxelsTouched, static_cast<uint32_t>(486219343));
|
||||
QCOMPARE(uTotalVoxelsTouched, static_cast<uint32_t>(29783248));
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestRaycast)
|
||||
|
Loading…
x
Reference in New Issue
Block a user