Made raycasting, ambient occlusion, and A* pathfinding independant of volume type.
This commit is contained in:
parent
27968973a4
commit
6a38d9fca7
@ -43,8 +43,8 @@ namespace PolyVox
|
||||
|
||||
/// This function provides the default method for checking whether a given voxel
|
||||
/// is vaid for the path computed by the AStarPathfinder.
|
||||
template <typename VoxelType>
|
||||
bool aStarDefaultVoxelValidator(const LargeVolume<VoxelType>* volData, const Vector3DInt32& v3dPos);
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
bool aStarDefaultVoxelValidator(const VolumeType<VoxelType>* volData, const Vector3DInt32& v3dPos);
|
||||
|
||||
/// Provides a configuration for the AStarPathfinder.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -57,20 +57,20 @@ namespace PolyVox
|
||||
///
|
||||
/// \sa AStarPathfinder
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
struct AStarPathfinderParams
|
||||
{
|
||||
public:
|
||||
AStarPathfinderParams
|
||||
(
|
||||
LargeVolume<VoxelType>* volData,
|
||||
VolumeType<VoxelType>* volData,
|
||||
const Vector3DInt32& v3dStart,
|
||||
const Vector3DInt32& v3dEnd,
|
||||
std::list<Vector3DInt32>* listResult,
|
||||
float fHBias = 1.0,
|
||||
uint32_t uMaxNoOfNodes = 10000,
|
||||
Connectivity connectivity = TwentySixConnected,
|
||||
polyvox_function<bool (const LargeVolume<VoxelType>*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator<VoxelType>,
|
||||
polyvox_function<bool (const VolumeType<VoxelType>*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator<VolumeType, VoxelType>,
|
||||
polyvox_function<void (float)> funcProgressCallback = 0
|
||||
)
|
||||
:volume(volData)
|
||||
@ -86,7 +86,7 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
/// This is the volume through which the AStarPathfinder must find a path.
|
||||
LargeVolume<VoxelType>* volume;
|
||||
VolumeType<VoxelType>* volume;
|
||||
|
||||
/// The start point for the pathfinding algorithm.
|
||||
Vector3DInt32 start;
|
||||
@ -125,7 +125,7 @@ namespace PolyVox
|
||||
/// you could check to ensure that the voxel above is empty and the voxel below is solid.
|
||||
///
|
||||
/// \sa aStarDefaultVoxelValidator
|
||||
polyvox_function<bool (const LargeVolume<VoxelType>*, const Vector3DInt32&)> isVoxelValidForPath;
|
||||
polyvox_function<bool (const VolumeType<VoxelType>*, const Vector3DInt32&)> isVoxelValidForPath;
|
||||
|
||||
/// This function is called by the AStarPathfinder to report on its progress in getting to
|
||||
/// the goal. The progress is reported by computing the distance from the closest node found
|
||||
@ -159,11 +159,11 @@ namespace PolyVox
|
||||
///
|
||||
/// \sa AStarPathfinderParams
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
class AStarPathfinder
|
||||
{
|
||||
public:
|
||||
AStarPathfinder(const AStarPathfinderParams<VoxelType>& params);
|
||||
AStarPathfinder(const AStarPathfinderParams<VolumeType, VoxelType>& params);
|
||||
|
||||
void execute();
|
||||
|
||||
@ -185,7 +185,7 @@ namespace PolyVox
|
||||
|
||||
float m_fProgress;
|
||||
|
||||
AStarPathfinderParams<VoxelType> m_params;
|
||||
AStarPathfinderParams<VolumeType, VoxelType> m_params;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,8 @@ namespace PolyVox
|
||||
/// volume and if its density is below that returned by the voxel's getDensity() function.
|
||||
/// \return true is the voxel is valid for the path
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
bool aStarDefaultVoxelValidator(const LargeVolume<VoxelType>* volData, const Vector3DInt32& v3dPos)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
bool aStarDefaultVoxelValidator(const VolumeType<VoxelType>* volData, const Vector3DInt32& v3dPos)
|
||||
{
|
||||
//Voxels are considered valid candidates for the path if they are inside the volume...
|
||||
if(volData->getEnclosingRegion().containsPoint(v3dPos) == false)
|
||||
@ -52,14 +52,14 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AStarPathfinder Class
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
AStarPathfinder<VoxelType>::AStarPathfinder(const AStarPathfinderParams<VoxelType>& params)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
AStarPathfinder<VolumeType, VoxelType>::AStarPathfinder(const AStarPathfinderParams<VolumeType, VoxelType>& params)
|
||||
:m_params(params)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void AStarPathfinder<VoxelType>::execute()
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void AStarPathfinder<VolumeType, VoxelType>::execute()
|
||||
{
|
||||
//Clear any existing nodes
|
||||
allNodes.clear();
|
||||
@ -191,8 +191,8 @@ namespace PolyVox
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void AStarPathfinder<VoxelType>::processNeighbour(const Vector3DInt32& neighbourPos, float neighbourGVal)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void AStarPathfinder<VolumeType, VoxelType>::processNeighbour(const Vector3DInt32& neighbourPos, float neighbourGVal)
|
||||
{
|
||||
bool bIsVoxelValidForPath = m_params.isVoxelValidForPath(m_params.volume, neighbourPos);
|
||||
if(!bIsVoxelValidForPath)
|
||||
@ -247,8 +247,8 @@ namespace PolyVox
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
float AStarPathfinder<VoxelType>::SixConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
float AStarPathfinder<VolumeType, VoxelType>::SixConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b)
|
||||
{
|
||||
//This is the only heuristic I'm sure of - just use the manhatten distance for the 6-connected case.
|
||||
uint32_t faceSteps = abs(a.getX()-b.getX()) + abs(a.getY()-b.getY()) + abs(a.getZ()-b.getZ());
|
||||
@ -256,8 +256,8 @@ namespace PolyVox
|
||||
return faceSteps * 1.0f;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
float AStarPathfinder<VoxelType>::EighteenConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
float AStarPathfinder<VolumeType, VoxelType>::EighteenConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b)
|
||||
{
|
||||
//I'm not sure of the correct heuristic for the 18-connected case, so I'm just letting it fall through to the
|
||||
//6-connected case. This means 'h' will be bigger than it should be, resulting in a faster path which may not
|
||||
@ -266,8 +266,8 @@ namespace PolyVox
|
||||
return SixConnectedCost(a,b);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
float AStarPathfinder<VoxelType>::TwentySixConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
float AStarPathfinder<VolumeType, VoxelType>::TwentySixConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b)
|
||||
{
|
||||
//Can't say I'm certain about this heuristic - if anyone has
|
||||
//a better idea of what it should be then please let me know.
|
||||
@ -288,8 +288,8 @@ namespace PolyVox
|
||||
return cornerSteps * sqrt_3 + edgeSteps * sqrt_2 + faceSteps * sqrt_1;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
float AStarPathfinder<VoxelType>::computeH(const Vector3DInt32& a, const Vector3DInt32& b)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
float AStarPathfinder<VolumeType, VoxelType>::computeH(const Vector3DInt32& a, const Vector3DInt32& b)
|
||||
{
|
||||
float hVal;
|
||||
|
||||
|
@ -29,19 +29,19 @@ freely, subject to the following restrictions:
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
template <typename VoxelType>
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
class AmbientOcclusionCalculator
|
||||
{
|
||||
public:
|
||||
AmbientOcclusionCalculator(LargeVolume<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement);
|
||||
AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement);
|
||||
~AmbientOcclusionCalculator();
|
||||
|
||||
void execute(void);
|
||||
|
||||
private:
|
||||
Region m_region;
|
||||
typename LargeVolume<VoxelType>::Sampler m_sampVolume;
|
||||
LargeVolume<VoxelType>* m_volInput;
|
||||
typename VolumeType<VoxelType>::Sampler m_sampVolume;
|
||||
VolumeType<VoxelType>* m_volInput;
|
||||
Array<3, uint8_t>* m_arrayResult;
|
||||
float m_fRayLength;
|
||||
|
||||
|
@ -28,10 +28,12 @@ freely, subject to the following restrictions:
|
||||
#include "PolyVoxImpl/RandomUnitVectors.h"
|
||||
#include "PolyVoxImpl/RandomVectors.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
template <typename VoxelType>
|
||||
AmbientOcclusionCalculator<VoxelType>::AmbientOcclusionCalculator(LargeVolume<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
AmbientOcclusionCalculator<VolumeType, VoxelType>::AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement)
|
||||
:m_region(region)
|
||||
,m_sampVolume(volInput)
|
||||
,m_volInput(volInput)
|
||||
@ -54,18 +56,18 @@ namespace PolyVox
|
||||
mIndexIncreament = 1;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
AmbientOcclusionCalculator<VoxelType>::~AmbientOcclusionCalculator()
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
AmbientOcclusionCalculator<VolumeType, VoxelType>::~AmbientOcclusionCalculator()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void AmbientOcclusionCalculator<VoxelType>::execute(void)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void AmbientOcclusionCalculator<VolumeType, VoxelType>::execute(void)
|
||||
{
|
||||
const int iRatioX = m_volInput->getWidth() / m_arrayResult->getDimension(0);
|
||||
const int iRatioY = m_volInput->getHeight() / m_arrayResult->getDimension(1);
|
||||
const int iRatioZ = m_volInput->getDepth() / m_arrayResult->getDimension(2);
|
||||
const int iRatioMax = std::max(std::max(iRatioX, iRatioY), iRatioZ);
|
||||
const int iRatioMax = (std::max)((std::max)(iRatioX, iRatioY), iRatioZ);
|
||||
|
||||
const float fRatioX = iRatioX;
|
||||
const float fRatioY = iRatioY;
|
||||
@ -82,7 +84,7 @@ namespace PolyVox
|
||||
const Vector3DFloat v3dOffset(0.5f,0.5f,0.5f);
|
||||
|
||||
RaycastResult raycastResult;
|
||||
Raycast<VoxelType> raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult);
|
||||
Raycast<VolumeType, VoxelType> raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult);
|
||||
|
||||
//This loop iterates over the bottom-lower-left voxel in each of the cells in the output array
|
||||
for(uint16_t z = m_region.getLowerCorner().getZ(); z <= m_region.getUpperCorner().getZ(); z += iRatioZ)
|
||||
|
@ -80,12 +80,12 @@ namespace PolyVox
|
||||
/// surace extractors. It's behaviour with the Marching Cubes surface extractor has not
|
||||
/// been tested yet.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
class Raycast
|
||||
{
|
||||
public:
|
||||
///Constructor
|
||||
Raycast(LargeVolume<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result);
|
||||
Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result);
|
||||
|
||||
///Sets the start position for the ray.
|
||||
void setStart(const Vector3DFloat& v3dStart);
|
||||
@ -100,8 +100,8 @@ namespace PolyVox
|
||||
|
||||
void doRaycast(float x1, float y1, float z1, float x2, float y2, float z2);
|
||||
|
||||
LargeVolume<VoxelType>* m_volData;
|
||||
typename LargeVolume<VoxelType>::Sampler m_sampVolume;
|
||||
VolumeType<VoxelType>* m_volData;
|
||||
typename VolumeType<VoxelType>::Sampler m_sampVolume;
|
||||
|
||||
Vector3DFloat m_v3dStart;
|
||||
Vector3DFloat m_v3dDirection;
|
||||
|
@ -30,8 +30,8 @@ namespace PolyVox
|
||||
/// represents the length of the ray.
|
||||
/// \param result An instance of RaycastResult in which the result will be stored.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
Raycast<VoxelType>::Raycast(LargeVolume<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
Raycast<VolumeType, VoxelType>::Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result)
|
||||
:m_volData(volData)
|
||||
,m_sampVolume(volData)
|
||||
,m_v3dStart(v3dStart)
|
||||
@ -43,8 +43,8 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dStart The starting position of the ray.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void Raycast<VoxelType>::setStart(const Vector3DFloat& v3dStart)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void Raycast<VolumeType, VoxelType>::setStart(const Vector3DFloat& v3dStart)
|
||||
{
|
||||
m_v3dStart = v3dStart;
|
||||
}
|
||||
@ -53,8 +53,8 @@ namespace PolyVox
|
||||
/// \param v3dDirection The direction of the ray. The length of this vector also
|
||||
/// represents the length of the ray.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void Raycast<VoxelType>::setDirection(const Vector3DFloat& v3dDirection)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void Raycast<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirection)
|
||||
{
|
||||
m_v3dDirection = v3dDirection;
|
||||
}
|
||||
@ -62,8 +62,8 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The result is stored in the RaycastResult instance which was passed to the constructor.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void Raycast<VoxelType>::execute(void)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void Raycast<VolumeType, VoxelType>::execute(void)
|
||||
{
|
||||
//The doRaycast function is assuming that it is iterating over the areas defined between
|
||||
//voxels. We actually want to define the areas as being centered on voxels (as this is
|
||||
@ -106,8 +106,8 @@ namespace PolyVox
|
||||
// It should simply read "if (ty <= tz)".
|
||||
//
|
||||
// This error was reported by Joey Hammer (PixelActive).
|
||||
template <typename VoxelType>
|
||||
void Raycast<VoxelType>::doRaycast(float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void Raycast<VolumeType, VoxelType>::doRaycast(float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
{
|
||||
int i = (int)floorf(x1);
|
||||
int j = (int)floorf(y1);
|
||||
|
@ -26,12 +26,12 @@ freely, subject to the following restrictions:
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
template <typename VoxelType>
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
class RaycastWithCallback
|
||||
{
|
||||
public:
|
||||
///Constructor
|
||||
RaycastWithCallback(LargeVolume<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function<bool(const Vector3DInt32& position)> funcCallback);
|
||||
RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function<bool(const Vector3DInt32& position)> funcCallback);
|
||||
|
||||
///Sets the start position for the ray.
|
||||
void setStart(const Vector3DFloat& v3dStart);
|
||||
@ -46,8 +46,8 @@ namespace PolyVox
|
||||
|
||||
void doRaycast(float x1, float y1, float z1, float x2, float y2, float z2);
|
||||
|
||||
LargeVolume<VoxelType>* m_volData;
|
||||
typename LargeVolume<VoxelType>::Sampler m_sampVolume;
|
||||
VolumeType<VoxelType>* m_volData;
|
||||
typename VolumeType<VoxelType>::Sampler m_sampVolume;
|
||||
|
||||
Vector3DFloat m_v3dStart;
|
||||
Vector3DFloat m_v3dDirection;
|
||||
|
@ -22,8 +22,8 @@ freely, subject to the following restrictions:
|
||||
*******************************************************************************/
|
||||
namespace PolyVox
|
||||
{
|
||||
template <typename VoxelType>
|
||||
RaycastWithCallback<VoxelType>::RaycastWithCallback(LargeVolume<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function<bool(const Vector3DInt32& position)> funcCallback)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
RaycastWithCallback<VolumeType, VoxelType>::RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function<bool(const Vector3DInt32& position)> funcCallback)
|
||||
:m_volData(volData)
|
||||
,m_sampVolume(volData)
|
||||
,m_v3dStart(v3dStart)
|
||||
@ -35,20 +35,20 @@ namespace PolyVox
|
||||
assert(m_funcCallback);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RaycastWithCallback<VoxelType>::setStart(const Vector3DFloat& v3dStart)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void RaycastWithCallback<VolumeType, VoxelType>::setStart(const Vector3DFloat& v3dStart)
|
||||
{
|
||||
m_v3dStart = v3dStart;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RaycastWithCallback<VoxelType>::setDirection(const Vector3DFloat& v3dDirection)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void RaycastWithCallback<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirection)
|
||||
{
|
||||
m_v3dDirection = v3dDirection;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RaycastWithCallback<VoxelType>::execute(void)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void RaycastWithCallback<VolumeType, VoxelType>::execute(void)
|
||||
{
|
||||
//The doRaycast function is assuming that it is iterating over the areas defined between
|
||||
//voxels. We actually want to define the areas as being centered on voxels (as this is
|
||||
@ -91,8 +91,8 @@ namespace PolyVox
|
||||
// It should simply read "if (ty <= tz)".
|
||||
//
|
||||
// This error was reported by Joey Hammer (PixelActive).
|
||||
template <typename VoxelType>
|
||||
void RaycastWithCallback<VoxelType>::doRaycast(float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
template< template<typename> class VolumeType, typename VoxelType>
|
||||
void RaycastWithCallback<VolumeType, VoxelType>::doRaycast(float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
{
|
||||
int i = (int)floorf(x1);
|
||||
int j = (int)floorf(y1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user