Merge branch 'develop' into feature/cubiquity-version
This commit is contained in:
@ -32,7 +32,6 @@ SET(CORE_SRC_FILES
|
||||
source/ArraySizes.cpp
|
||||
source/AStarPathfinder.cpp
|
||||
source/MinizCompressor.cpp
|
||||
source/Log.cpp
|
||||
source/Region.cpp
|
||||
source/VertexTypes.cpp
|
||||
)
|
||||
@ -66,7 +65,6 @@ SET(CORE_INC_FILES
|
||||
include/PolyVoxCore/LargeVolume.h
|
||||
include/PolyVoxCore/LargeVolume.inl
|
||||
include/PolyVoxCore/LargeVolumeSampler.inl
|
||||
include/PolyVoxCore/Log.h
|
||||
include/PolyVoxCore/LowPassFilter.h
|
||||
include/PolyVoxCore/LowPassFilter.inl
|
||||
include/PolyVoxCore/MarchingCubesSurfaceExtractor.h
|
||||
@ -75,6 +73,8 @@ SET(CORE_INC_FILES
|
||||
include/PolyVoxCore/MaterialDensityPair.h
|
||||
include/PolyVoxCore/MinizCompressor.h
|
||||
include/PolyVoxCore/PolyVoxForwardDeclarations.h
|
||||
include/PolyVoxCore/Picking.h
|
||||
include/PolyVoxCore/Picking.inl
|
||||
include/PolyVoxCore/RawVolume.h
|
||||
include/PolyVoxCore/RawVolume.inl
|
||||
include/PolyVoxCore/RawVolumeSampler.inl
|
||||
|
@ -298,7 +298,7 @@ namespace PolyVox
|
||||
hVal = SixConnectedCost(a, b);
|
||||
break;
|
||||
default:
|
||||
POLYVOX_ASSERT(false, "Invalid case");
|
||||
POLYVOX_THROW(std::invalid_argument, "Connectivity parameter has an unrecognised value.");
|
||||
}
|
||||
|
||||
//Sanity checks in debug mode. These can come out eventually, but I
|
||||
|
@ -34,15 +34,24 @@ namespace PolyVox
|
||||
template<typename VolumeType, typename IsVoxelTransparentCallback>
|
||||
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, 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)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array width.");
|
||||
}
|
||||
if(volInput->getHeight() % 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)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array depth.");
|
||||
}
|
||||
|
||||
uint16_t uRandomUnitVectorIndex = 0;
|
||||
uint16_t uRandomVectorIndex = 0;
|
||||
uint16_t uIndexIncreament;
|
||||
|
||||
//Make sure that the size of the volume is an exact multiple of the size of the array.
|
||||
POLYVOX_ASSERT(volInput->getWidth() % arrayResult->getDimension(0) == 0, "Volume width must be an exact multiple of array width.");
|
||||
POLYVOX_ASSERT(volInput->getHeight() % arrayResult->getDimension(1) == 0, "Volume height must be an exact multiple of array height.");
|
||||
POLYVOX_ASSERT(volInput->getDepth() % arrayResult->getDimension(2) == 0, "Volume depth must be an exact multiple of array depth.");
|
||||
|
||||
//Our initial indices. It doesn't matter exactly what we set here, but the code below makes
|
||||
//sure they are different for different regions which helps reduce tiling patterns in the results.
|
||||
uRandomUnitVectorIndex += region.getLowerX() + region.getLowerY() + region.getLowerZ();
|
||||
|
@ -73,7 +73,11 @@ namespace PolyVox
|
||||
template <uint32_t noOfDims, typename ElementType>
|
||||
SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex)
|
||||
{
|
||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
|
||||
return
|
||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||
m_pDimensions+1, m_pOffsets+1);
|
||||
@ -91,7 +95,11 @@ namespace PolyVox
|
||||
template <uint32_t noOfDims, typename ElementType>
|
||||
const SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex) const
|
||||
{
|
||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
|
||||
return
|
||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||
m_pDimensions+1, m_pOffsets+1);
|
||||
@ -139,7 +147,10 @@ namespace PolyVox
|
||||
m_uNoOfElements = 1;
|
||||
for (uint32_t i = 0; i<noOfDims; i++)
|
||||
{
|
||||
POLYVOX_ASSERT(pDimensions[i] != 0, "Invalid dimension");
|
||||
if(pDimensions[i] == 0)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Invalid array dimension");
|
||||
}
|
||||
|
||||
m_uNoOfElements *= pDimensions[i];
|
||||
m_pDimensions[i] = pDimensions[i];
|
||||
@ -186,7 +197,11 @@ namespace PolyVox
|
||||
template <uint32_t noOfDims, typename ElementType>
|
||||
uint32_t Array<noOfDims, ElementType>::getDimension(uint32_t uDimension)
|
||||
{
|
||||
POLYVOX_ASSERT(uDimension < noOfDims, "Dimension out of range");
|
||||
if(uDimension >= noOfDims)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array dimension out of range");
|
||||
}
|
||||
|
||||
return m_pDimensions[uDimension];
|
||||
}
|
||||
|
||||
@ -198,14 +213,14 @@ namespace PolyVox
|
||||
,m_uNoOfElements(0)
|
||||
{
|
||||
//Not implemented
|
||||
POLYVOX_ASSERT(false, "Not implemented.");
|
||||
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
|
||||
}
|
||||
|
||||
template <uint32_t noOfDims, typename ElementType>
|
||||
Array<noOfDims, ElementType>& Array<noOfDims, ElementType>::operator=(const Array<noOfDims, ElementType>& rhs)
|
||||
{
|
||||
//Not implemented
|
||||
POLYVOX_ASSERT(false, "Not implemented.");
|
||||
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -251,14 +266,22 @@ namespace PolyVox
|
||||
template <typename ElementType>
|
||||
ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex)
|
||||
{
|
||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
|
||||
return m_pElements[uIndex];
|
||||
}
|
||||
|
||||
template <typename ElementType>
|
||||
const ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex) const
|
||||
{
|
||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
|
||||
return m_pElements[uIndex];
|
||||
}
|
||||
|
||||
@ -307,14 +330,14 @@ namespace PolyVox
|
||||
,m_pDimensions(0)
|
||||
{
|
||||
//Not implemented
|
||||
POLYVOX_ASSERT(false, "Not implemented.");
|
||||
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
|
||||
}
|
||||
|
||||
template <typename ElementType>
|
||||
Array<1, ElementType>& Array<1, ElementType>::operator=(const Array<1, ElementType>& rhs)
|
||||
{
|
||||
//Not implemented
|
||||
POLYVOX_ASSERT(false, "Not implemented.");
|
||||
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ freely, subject to the following restrictions:
|
||||
#ifndef __PolyVox_BaseVolume_H__
|
||||
#define __PolyVox_BaseVolume_H__
|
||||
|
||||
#include "PolyVoxCore/Log.h"
|
||||
#include "PolyVoxCore/Region.h"
|
||||
#include "PolyVoxCore/Vector.h"
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
BaseVolume<VoxelType>::BaseVolume(const BaseVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
||||
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -59,14 +59,14 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This function should never be called. Copying volumes by value would be expensive, and we want to prevent users from doing
|
||||
/// it by accident (such as when passing them as paramenters to functions). That said, there are times when you really do want to
|
||||
/// make a copy of a volume and in this case you should look at the Volumeresampler.
|
||||
/// make a copy of a volume and in this case you should look at the VolumeResampler.
|
||||
///
|
||||
/// \sa VolumeResampler
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
BaseVolume<VoxelType>& BaseVolume<VoxelType>::operator=(const BaseVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
||||
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -162,7 +162,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& /*v3dPos*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxelAt(const Vector3DInt32& /*v3dPos*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& /*v3dPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
@ -244,7 +244,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
bool BaseVolume<VoxelType>::setVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
bool BaseVolume<VoxelType>::setVoxelAt(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -375,7 +375,7 @@ namespace PolyVox
|
||||
default:
|
||||
{
|
||||
//Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid case.");
|
||||
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
|
@ -37,24 +37,28 @@ namespace PolyVox
|
||||
public:
|
||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
return m_pVolume.getVoxelAt(uXPos, uYPos, uZPos);
|
||||
}
|
||||
|
||||
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
|
||||
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
void setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
m_pVolume.setVoxelAtConst(uXPos, uYPos, uZPos, tValue);
|
||||
}
|
||||
|
||||
void setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
|
||||
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
}
|
||||
|
@ -220,9 +220,9 @@ namespace PolyVox
|
||||
}
|
||||
}
|
||||
|
||||
// If we exit the loop here then apparently all the slots were full but none of them matched. I don't think
|
||||
// this can happen so let's put an assert to make sure. If you hit this assert then please report it to us!
|
||||
POLYVOX_ASSERT(false, "All slots full but no matches.");
|
||||
// If we exit the loop here then apparently all the slots were full but none of them matched.
|
||||
// This shouldn't ever happen, so if it does it is probably a bug in PolyVox. Please report it to us!
|
||||
POLYVOX_THROW(std::runtime_error, "All slots full but no matches during cubic surface extraction. This is probably a bug in PolyVox");
|
||||
return -1; //Should never happen.
|
||||
}
|
||||
|
||||
|
@ -60,10 +60,10 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType Block<VoxelType>::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
|
||||
{
|
||||
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
|
||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
||||
|
||||
return m_tUncompressedData
|
||||
@ -83,10 +83,10 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
|
||||
{
|
||||
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
|
||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
||||
|
||||
m_tUncompressedData
|
||||
@ -108,9 +108,6 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::initialise(uint16_t uSideLength)
|
||||
{
|
||||
//Debug mode validation
|
||||
POLYVOX_ASSERT(isPowerOf2(uSideLength), "Block side length must be a power of two.");
|
||||
|
||||
//Release mode validation
|
||||
if(!isPowerOf2(uSideLength))
|
||||
{
|
||||
@ -141,8 +138,16 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::compress(Compressor* pCompressor)
|
||||
{
|
||||
POLYVOX_ASSERT(pCompressor, "Compressor is not valid");
|
||||
POLYVOX_ASSERT(m_bIsCompressed == false, "Attempted to compress block which is already flagged as compressed.");
|
||||
if(m_bIsCompressed)
|
||||
{
|
||||
POLYVOX_THROW(invalid_operation, "Attempted to compress block which is already flagged as compressed.");
|
||||
}
|
||||
|
||||
if(!pCompressor)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "A valid compressor must be provided");
|
||||
}
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData != 0, "No uncompressed data is present.");
|
||||
|
||||
//If the uncompressed data hasn't actually been
|
||||
@ -212,8 +217,16 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::uncompress(Compressor* pCompressor)
|
||||
{
|
||||
POLYVOX_ASSERT(pCompressor, "Compressor is not valid");
|
||||
POLYVOX_ASSERT(m_bIsCompressed == true, "Attempted to uncompress block which is not flagged as compressed.");
|
||||
if(!m_bIsCompressed)
|
||||
{
|
||||
POLYVOX_THROW(invalid_operation, "Attempted to uncompress block which is not flagged as compressed.");
|
||||
}
|
||||
|
||||
if(!pCompressor)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "A valid compressor must be provided");
|
||||
}
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData == 0, "Uncompressed data already exists.");
|
||||
|
||||
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
||||
|
@ -26,14 +26,19 @@ freely, subject to the following restrictions:
|
||||
|
||||
#include "PolyVoxCore/Impl/Config.h"
|
||||
|
||||
#include <cstdlib> //For std::exit
|
||||
#include <iostream> //For std::cerr
|
||||
#include <cstdlib> // For std::exit
|
||||
#include <iostream> // For std::cerr
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <string.h> // Exception constuctors take strings.
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// In Visual Studio we can use this function to go into the debugger.
|
||||
#define POLYVOX_HALT() __debugbreak()
|
||||
#else
|
||||
#define POLYVOX_HALT() std::exit(EXIT_FAILURE)
|
||||
// On other platforms we just halt by forcing a crash.
|
||||
// Hopefully this puts us in the debugger if one is running
|
||||
#define POLYVOX_HALT() *((unsigned int*)0) = 0xDEAD
|
||||
#endif
|
||||
|
||||
// Macros cannot contain #ifdefs, but some of our macros need to disable warnings and such warning supression is
|
||||
@ -51,6 +56,44 @@ freely, subject to the following restrictions:
|
||||
|
||||
#define POLYVOX_UNUSED(x) do { (void)sizeof(x); } while(0)
|
||||
|
||||
/*
|
||||
* Logging
|
||||
* --------
|
||||
* PolyVox provides basic logging facilities which can be redirected by your application.
|
||||
*/
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
class LogLevels
|
||||
{
|
||||
public:
|
||||
enum LogLevel
|
||||
{
|
||||
Debug,
|
||||
Info,
|
||||
Warning,
|
||||
Error,
|
||||
Fatal
|
||||
};
|
||||
};
|
||||
typedef LogLevels::LogLevel LogLevel;
|
||||
|
||||
typedef void (*LogHandler)(const std::string& message, LogLevel logLevel);
|
||||
|
||||
LogHandler getLogHandler();
|
||||
void setLogHandler(LogHandler newHandler);
|
||||
|
||||
// The actual logging function
|
||||
void log(const std::string& message, LogLevel logLevel);
|
||||
|
||||
// Some handy wrappers
|
||||
void logDebug (const std::string& message);
|
||||
void logInfo (const std::string& message);
|
||||
void logWarning(const std::string& message);
|
||||
void logError (const std::string& message);
|
||||
void logFatal (const std::string& message);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assertions
|
||||
* ----------
|
||||
@ -71,12 +114,14 @@ freely, subject to the following restrictions:
|
||||
{ \
|
||||
if (!(condition)) \
|
||||
{ \
|
||||
std::cerr << std::endl << std::endl; \
|
||||
std::cerr << " PolyVox Assertion Failed!" << std::endl; \
|
||||
std::cerr << " =========================" << std::endl; \
|
||||
std::cerr << " Condition: " << #condition << std::endl; \
|
||||
std::cerr << " Message: " << (message) << std::endl; \
|
||||
std::cerr << " Location: " << "Line " << __LINE__ << " of " << __FILE__ << std::endl << std::endl; \
|
||||
std::stringstream ss; \
|
||||
ss << std::endl << std::endl; \
|
||||
ss << " PolyVox Assertion Failed!" << std::endl; \
|
||||
ss << " =========================" << std::endl; \
|
||||
ss << " Condition: " << #condition << std::endl; \
|
||||
ss << " Message: " << (message) << std::endl; \
|
||||
ss << " Location: " << "Line " << __LINE__ << " of " << __FILE__ << std::endl << std::endl; \
|
||||
logFatal(ss.str()); \
|
||||
POLYVOX_HALT(); \
|
||||
} \
|
||||
} while(0) \
|
||||
@ -130,7 +175,9 @@ freely, subject to the following restrictions:
|
||||
* ...
|
||||
*/
|
||||
#ifdef POLYVOX_THROW_ENABLED
|
||||
#define POLYVOX_THROW(type, message) throw type((message))
|
||||
#define POLYVOX_THROW(type, message) \
|
||||
log(message, LogLevels::Error); \
|
||||
throw type((message))
|
||||
#else
|
||||
namespace PolyVox
|
||||
{
|
||||
@ -141,8 +188,37 @@ freely, subject to the following restrictions:
|
||||
}
|
||||
|
||||
#define POLYVOX_THROW(type, message) \
|
||||
log(message, LogLevels::Error); \
|
||||
type except = (type)((message)); \
|
||||
getThrowHandler()((except), __FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
/// A general purpose exception to indicate that an operation cannot be peformed.
|
||||
class invalid_operation : public std::logic_error
|
||||
{
|
||||
public:
|
||||
explicit invalid_operation(const std::string& message)
|
||||
: logic_error(message.c_str()) {}
|
||||
|
||||
explicit invalid_operation(const char *message)
|
||||
: logic_error(message) {}
|
||||
};
|
||||
|
||||
/// Thrown to indicate that a function is deliberatly not implmented. For example, perhaps you called a function
|
||||
/// in a base class whereas you are supposed to use a derived class which implements the function, or perhaps the
|
||||
/// function is not defined for a particular template parameter. It may be that the function is required to
|
||||
/// compile sucessfully but it should not be called.
|
||||
class not_implemented : public std::logic_error
|
||||
{
|
||||
public:
|
||||
explicit not_implemented(const std::string& message)
|
||||
: logic_error(message.c_str()) {}
|
||||
|
||||
explicit not_implemented(const char *message)
|
||||
: logic_error(message) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__PolyVox_ErrorHandling_H__
|
||||
|
@ -28,7 +28,11 @@ namespace PolyVox
|
||||
template <uint32_t noOfDims, typename ElementType>
|
||||
SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex)
|
||||
{
|
||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
|
||||
return
|
||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||
m_pDimensions+1, m_pOffsets+1);
|
||||
@ -37,7 +41,11 @@ namespace PolyVox
|
||||
template <uint32_t noOfDims, typename ElementType>
|
||||
const SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex) const
|
||||
{
|
||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
|
||||
return
|
||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||
m_pDimensions+1, m_pOffsets+1);
|
||||
@ -56,14 +64,22 @@ namespace PolyVox
|
||||
template <typename ElementType>
|
||||
ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex)
|
||||
{
|
||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
|
||||
return m_pElements[uIndex];
|
||||
}
|
||||
|
||||
template <typename ElementType>
|
||||
const ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex) const
|
||||
{
|
||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
|
||||
return m_pElements[uIndex];
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ namespace PolyVox
|
||||
const Type& v0,const Type& v1,
|
||||
const float x)
|
||||
{
|
||||
//This function is called frequently and is very short, so assert rather than exceptions.
|
||||
POLYVOX_ASSERT((x >= 0.0f) && (x <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
||||
|
||||
//Interpolate along X
|
||||
@ -44,6 +45,7 @@ namespace PolyVox
|
||||
const Type& v00,const Type& v10,const Type& v01,const Type& v11,
|
||||
const float x, const float y)
|
||||
{
|
||||
//This function is called frequently and is very short, so assert rather than exceptions.
|
||||
POLYVOX_ASSERT((x >= 0.0f) && (y >= 0.0f) &&
|
||||
(x <= 1.0f) && (y <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
||||
|
||||
@ -63,6 +65,7 @@ namespace PolyVox
|
||||
const Type& v001,const Type& v101,const Type& v011,const Type& v111,
|
||||
const float x, const float y, const float z)
|
||||
{
|
||||
//This function is called frequently and is very short, so assert rather than exceptions.
|
||||
POLYVOX_ASSERT((x >= 0.0f) && (y >= 0.0f) && (z >= 0.0f) &&
|
||||
(x <= 1.0f) && (y <= 1.0f) && (z <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
||||
|
||||
|
@ -27,7 +27,6 @@ freely, subject to the following restrictions:
|
||||
#include "PolyVoxCore/BaseVolume.h"
|
||||
#include "Impl/Block.h"
|
||||
#include "PolyVoxCore/Compressor.h"
|
||||
#include "PolyVoxCore/Log.h"
|
||||
#include "PolyVoxCore/Region.h"
|
||||
#include "PolyVoxCore/Vector.h"
|
||||
|
||||
|
@ -90,7 +90,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
LargeVolume<VoxelType>::LargeVolume(const LargeVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
||||
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -112,7 +112,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
LargeVolume<VoxelType>& LargeVolume<VoxelType>::operator=(const LargeVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
||||
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -124,6 +124,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
@ -228,7 +229,7 @@ namespace PolyVox
|
||||
default:
|
||||
{
|
||||
//Should never happen
|
||||
POLYVOX_ASSERT(false, "Invlaid case.");
|
||||
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
@ -282,6 +283,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
bool LargeVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
@ -445,13 +447,8 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void LargeVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
||||
{
|
||||
//Debug mode validation
|
||||
POLYVOX_ASSERT(uBlockSideLength > 0, "Block side length cannot be zero.");
|
||||
POLYVOX_ASSERT(isPowerOf2(uBlockSideLength), "Block side length must be a power of two.");
|
||||
POLYVOX_ASSERT(m_pCompressor, "You must provide a compressor for the LargeVolume to use.");
|
||||
|
||||
//Release mode validation
|
||||
{
|
||||
//Validate parameters
|
||||
if(uBlockSideLength == 0)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Block side length cannot be zero.");
|
||||
|
@ -143,7 +143,7 @@ namespace PolyVox
|
||||
}*/
|
||||
|
||||
//Need to think what effect this has on any existing iterators.
|
||||
POLYVOX_ASSERT(false, "This function cnnot be used on LargeVolume samplers.");
|
||||
POLYVOX_THROW(not_implemented, "This function cannot be used on LargeVolume samplers.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,63 +0,0 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2005-2009 David 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.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __PolyVox_Log_H__
|
||||
#define __PolyVox_Log_H__
|
||||
|
||||
#include "Impl/TypeDef.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
//Note: The functions in this file are not for the user to call - they are
|
||||
//intended for internal use only. The only exception is that you may set the
|
||||
//logHandler pointer to point at your own handling funtion for printing, etc.
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Log levels for filtering logging events
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
enum LogSeverity
|
||||
{
|
||||
LS_DEBUG, ///< Only displayed if it is a debug build
|
||||
LS_INFO,
|
||||
LS_WARN,
|
||||
LS_ERROR
|
||||
};
|
||||
|
||||
POLYVOX_API extern void (*logHandler)(std::string, int severity);
|
||||
}
|
||||
|
||||
//Debug severity messages are only used if we are a debug build
|
||||
#ifdef _DEBUG
|
||||
#define POLYVOX_LOG_DEBUG(message) if(logHandler){logHandler(message, LS_DEBUG);}
|
||||
#else
|
||||
#define POLYVOX_LOG_DEBUG(message)
|
||||
#endif
|
||||
|
||||
//Other severity levels work in both debug and release
|
||||
#define POLYVOX_LOG_INFO(message) if(logHandler){logHandler(message, LS_INFO);}
|
||||
#define POLYVOX_LOG_WARN(message) if(logHandler){logHandler(message, LS_WARN);}
|
||||
#define POLYVOX_LOG_ERROR(message) if(logHandler){logHandler(message, LS_ERROR);}
|
||||
|
||||
#endif
|
@ -39,14 +39,15 @@ namespace PolyVox
|
||||
,m_uKernelSize(uKernelSize)
|
||||
{
|
||||
//Kernel size must be at least three
|
||||
POLYVOX_ASSERT(m_uKernelSize >= 3, "Kernel size must be at least three");
|
||||
m_uKernelSize = std::max(m_uKernelSize, static_cast<uint32_t>(3)); //For release builds
|
||||
if(m_uKernelSize < 3)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Kernel size must be at least three");
|
||||
}
|
||||
|
||||
//Kernel size must be odd
|
||||
POLYVOX_ASSERT(m_uKernelSize % 2 == 1, "Kernel size must be odd");
|
||||
if(m_uKernelSize % 2 == 0) //For release builds
|
||||
if(m_uKernelSize % 2 == 0)
|
||||
{
|
||||
m_uKernelSize++;
|
||||
POLYVOX_THROW(std::invalid_argument, "Kernel size must be odd");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,49 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2005-2009 David 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 "PolyVoxCore/Log.h"
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
void (*logHandler)(std::string, int severity) = 0;
|
||||
}
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2013 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.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __PolyVox_Picking_H__
|
||||
#define __PolyVox_Picking_H__
|
||||
|
||||
#include "PolyVoxCore/Vector.h"
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
/**
|
||||
* A structure containing the information about a picking operation
|
||||
*/
|
||||
struct PickResult
|
||||
{
|
||||
PickResult() : didHit(false) {}
|
||||
bool didHit; ///< Did the picking operation hit anything
|
||||
Vector3DInt32 hitVoxel; ///< The location of the solid voxel it hit
|
||||
Vector3DInt32 previousVoxel; ///< The location of the voxel before the one it hit
|
||||
};
|
||||
|
||||
/// Pick the first solid voxel along a vector
|
||||
template<typename VolumeType>
|
||||
PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample);
|
||||
}
|
||||
|
||||
#include "PolyVoxCore/Picking.inl"
|
||||
|
||||
#endif //__PolyVox_Picking_H__
|
84
library/PolyVoxCore/include/PolyVoxCore/Picking.inl
Normal file
84
library/PolyVoxCore/include/PolyVoxCore/Picking.inl
Normal file
@ -0,0 +1,84 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2013 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 "PolyVoxCore/Raycast.h"
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
namespace
|
||||
{
|
||||
/**
|
||||
* This is just an implementation class for the pickVoxel function
|
||||
*
|
||||
* It makes note of the sort of empty voxel you're looking for in the constructor.
|
||||
*
|
||||
* Each time the operator() is called:
|
||||
* * if it's hit a voxel it sets up the result and returns false
|
||||
* * otherwise it preps the result for the next iteration and returns true
|
||||
*/
|
||||
template <typename VolumeType>
|
||||
class RaycastPickingFunctor
|
||||
{
|
||||
public:
|
||||
RaycastPickingFunctor(const typename VolumeType::VoxelType& emptyVoxelExample)
|
||||
:m_emptyVoxelExample(emptyVoxelExample)
|
||||
,m_result()
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const typename VolumeType::Sampler& sampler)
|
||||
{
|
||||
if(sampler.getVoxel() != m_emptyVoxelExample) //If we've hit something
|
||||
{
|
||||
m_result.didHit = true;
|
||||
m_result.hitVoxel = sampler.getPosition();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_result.previousVoxel = sampler.getPosition();
|
||||
|
||||
return true;
|
||||
}
|
||||
const typename VolumeType::VoxelType& m_emptyVoxelExample;
|
||||
PickResult m_result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \param volData The volume to pass the ray though
|
||||
* \param v3dStart The start position in the volume
|
||||
* \param v3dDirectionAndLength The direction and length of the ray
|
||||
* \param emptyVoxelExample The value used to represent empty voxels in your volume
|
||||
*
|
||||
* \return A PickResult containing the hit information
|
||||
*/
|
||||
template<typename VolumeType>
|
||||
PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample)
|
||||
{
|
||||
RaycastPickingFunctor<VolumeType> functor(emptyVoxelExample);
|
||||
|
||||
raycastWithDirection(volData, v3dStart, v3dDirectionAndLength, functor);
|
||||
|
||||
return functor.m_result;
|
||||
}
|
||||
}
|
@ -25,7 +25,6 @@ freely, subject to the following restrictions:
|
||||
#define __PolyVox_RawVolume_H__
|
||||
|
||||
#include "PolyVoxCore/BaseVolume.h"
|
||||
#include "PolyVoxCore/Log.h"
|
||||
#include "PolyVoxCore/Region.h"
|
||||
#include "PolyVoxCore/Vector.h"
|
||||
|
||||
|
@ -47,7 +47,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
RawVolume<VoxelType>::RawVolume(const RawVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
||||
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -70,7 +70,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
RawVolume<VoxelType>& RawVolume<VoxelType>::operator=(const RawVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
||||
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -82,6 +82,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
|
||||
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
|
||||
@ -186,7 +187,7 @@ namespace PolyVox
|
||||
default:
|
||||
{
|
||||
//Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid case.");
|
||||
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
@ -254,10 +255,18 @@ namespace PolyVox
|
||||
{
|
||||
this->m_regValidRegion = regValidRegion;
|
||||
|
||||
//Ensure dimensions of the specified Region are valid
|
||||
POLYVOX_ASSERT(this->getWidth() > 0, "Volume width must be greater than zero.");
|
||||
POLYVOX_ASSERT(this->getHeight() > 0, "Volume width must be greater than zero.");
|
||||
POLYVOX_ASSERT(this->getDepth() > 0, "Volume width must be greater than zero.");
|
||||
if(this->getWidth() <= 0)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Volume width must be greater than zero.");
|
||||
}
|
||||
if(this->getHeight() <= 0)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Volume height must be greater than zero.");
|
||||
}
|
||||
if(this->getDepth() <= 0)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Volume depth must be greater than zero.");
|
||||
}
|
||||
|
||||
//Create the data
|
||||
m_pData = new VoxelType[this->getWidth() * this->getHeight()* this->getDepth()];
|
||||
|
@ -27,7 +27,6 @@ freely, subject to the following restrictions:
|
||||
#include "Impl/Utility.h"
|
||||
|
||||
#include "PolyVoxCore/BaseVolume.h"
|
||||
#include "PolyVoxCore/Log.h"
|
||||
#include "PolyVoxCore/Region.h"
|
||||
#include "PolyVoxCore/Vector.h"
|
||||
|
||||
|
@ -48,7 +48,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
SimpleVolume<VoxelType>::SimpleVolume(const SimpleVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
||||
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -70,7 +70,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
SimpleVolume<VoxelType>& SimpleVolume<VoxelType>::operator=(const SimpleVolume<VoxelType>& /*rhs*/)
|
||||
{
|
||||
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
||||
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -82,6 +82,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
@ -186,7 +187,7 @@ namespace PolyVox
|
||||
default:
|
||||
{
|
||||
//Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid case.");
|
||||
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
@ -212,6 +213,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
bool SimpleVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
@ -246,12 +248,7 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void SimpleVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
||||
{
|
||||
//Debug mode validation
|
||||
POLYVOX_ASSERT(uBlockSideLength >= 8, "Block side length should be at least 8");
|
||||
POLYVOX_ASSERT(uBlockSideLength <= 256, "Block side length should not be more than 256");
|
||||
POLYVOX_ASSERT(isPowerOf2(uBlockSideLength), "Block side length must be a power of two.");
|
||||
|
||||
{
|
||||
//Release mode validation
|
||||
if(uBlockSideLength < 8)
|
||||
{
|
||||
|
@ -52,10 +52,10 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::Block::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
|
||||
{
|
||||
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
|
||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
|
||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
|
||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
|
||||
|
||||
return m_tUncompressedData
|
||||
@ -75,10 +75,10 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void SimpleVolume<VoxelType>::Block::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
|
||||
{
|
||||
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
|
||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
|
||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
|
||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
|
||||
|
||||
m_tUncompressedData
|
||||
@ -105,9 +105,6 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void SimpleVolume<VoxelType>::Block::initialise(uint16_t uSideLength)
|
||||
{
|
||||
//Debug mode validation
|
||||
POLYVOX_ASSERT(isPowerOf2(uSideLength), "Block side length must be a power of two.");
|
||||
|
||||
//Release mode validation
|
||||
if(!isPowerOf2(uSideLength))
|
||||
{
|
||||
|
@ -414,7 +414,11 @@ namespace PolyVox
|
||||
template <uint32_t Size, typename StorageType, typename OperationType>
|
||||
inline StorageType Vector<Size, StorageType, OperationType>::getElement(uint32_t index) const
|
||||
{
|
||||
POLYVOX_ASSERT(index < Size, "Attempted to access invalid vector element.");
|
||||
if(index >= Size)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element.");
|
||||
}
|
||||
|
||||
return m_tElements[index];
|
||||
}
|
||||
|
||||
@ -465,7 +469,11 @@ namespace PolyVox
|
||||
template <uint32_t Size, typename StorageType, typename OperationType>
|
||||
inline void Vector<Size, StorageType, OperationType>::setElement(uint32_t index, StorageType tValue)
|
||||
{
|
||||
POLYVOX_ASSERT(index < Size, "Attempted to access invalid vector element.");
|
||||
if(index >= Size)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element.");
|
||||
}
|
||||
|
||||
m_tElements[index] = tValue;
|
||||
}
|
||||
|
||||
@ -645,10 +653,17 @@ namespace PolyVox
|
||||
inline void Vector<Size, StorageType, OperationType>::normalise(void)
|
||||
{
|
||||
float fLength = this->length();
|
||||
if(fLength <= 0.0)
|
||||
{
|
||||
POLYVOX_THROW(invalid_operation, "Cannot normalise a vector with a length of zero");
|
||||
}
|
||||
|
||||
for(uint32_t ct = 0; ct < Size; ++ct)
|
||||
{
|
||||
// Standard float rules apply for divide-by-zero
|
||||
m_tElements[ct] /= fLength;
|
||||
|
||||
//This shouldn't happen as we had the length check earlier. So it's probably a bug if it does happen.
|
||||
POLYVOX_ASSERT(m_tElements[ct] == m_tElements[ct], "Obtained NAN during vector normalisation. Perhaps the input vector was too short?");
|
||||
}
|
||||
}
|
||||
|
@ -23,49 +23,135 @@ freely, subject to the following restrictions:
|
||||
|
||||
#include "PolyVoxCore/Impl/ErrorHandling.h"
|
||||
|
||||
#ifndef POLYVOX_THROW_ENABLED
|
||||
namespace PolyVox
|
||||
namespace PolyVox
|
||||
{
|
||||
void defaultLogHandler(const std::string& message, LogLevel logLevel)
|
||||
{
|
||||
void defaultThrowHandler(std::exception& e, const char* file, int line)
|
||||
switch(logLevel)
|
||||
{
|
||||
std::cerr << std::endl << std::endl; \
|
||||
std::cerr << " PolyVox exception thrown!" << std::endl; \
|
||||
std::cerr << " =========================" << std::endl; \
|
||||
std::cerr << " PolyVox has tried to throw an exception but it was built without support" << std::endl; \
|
||||
std::cerr << " for exceptions. In this scenario PolyVox will call a 'throw handler'" << std::endl; \
|
||||
std::cerr << " and this message is being printed by the default throw handler." << std::endl << std::endl; \
|
||||
|
||||
std::cerr << " If you don't want to enable exceptions then you should try to determine why" << std::endl; \
|
||||
std::cerr << " this exception was thrown and make sure it doesn't happen again. If it was" << std::endl; \
|
||||
std::cerr << " due to something like an invalid argument to a function then you should be" << std::endl; \
|
||||
std::cerr << " able to fix it quite easily by validating parameters as appropriate. More" << std::endl; \
|
||||
std::cerr << " complex exception scenarios (out of memory, etc) might be harder to fix and" << std::endl; \
|
||||
std::cerr << " you should replace this default handler with something which is more" << std::endl; \
|
||||
std::cerr << " meaningful to your users." << std::endl << std::endl; \
|
||||
|
||||
std::cerr << " Exception details" << std::endl; \
|
||||
std::cerr << " -----------------" << std::endl; \
|
||||
std::cerr << " Line: " << line << std::endl; \
|
||||
std::cerr << " File: " << file << std::endl; \
|
||||
std::cerr << " Message: " << e.what() << std::endl << std::endl; \
|
||||
|
||||
POLYVOX_HALT(); \
|
||||
}
|
||||
|
||||
ThrowHandler& getThrowHandlerInstance()
|
||||
{
|
||||
static ThrowHandler s_fThrowHandler = &defaultThrowHandler;
|
||||
return s_fThrowHandler;
|
||||
}
|
||||
|
||||
ThrowHandler getThrowHandler()
|
||||
{
|
||||
return getThrowHandlerInstance();
|
||||
}
|
||||
|
||||
void setThrowHandler(ThrowHandler fNewHandler)
|
||||
{
|
||||
getThrowHandlerInstance() = fNewHandler;
|
||||
case LogLevels::Debug:
|
||||
{
|
||||
// Debug messages are not output by this default log handler.
|
||||
// Provide a custom handler if you want to process them.
|
||||
break;
|
||||
}
|
||||
case LogLevels::Info:
|
||||
{
|
||||
std::cout << "Info: " << message.c_str() << std::endl;
|
||||
break;
|
||||
}
|
||||
case LogLevels::Warning:
|
||||
{
|
||||
std::cerr << "Warning: " << message.c_str() << std::endl;
|
||||
break;
|
||||
}
|
||||
case LogLevels::Error:
|
||||
{
|
||||
std::cerr << "Error: " << message.c_str() << std::endl;
|
||||
break;
|
||||
}
|
||||
case LogLevels::Fatal:
|
||||
{
|
||||
std::cerr << "Fatal: " << message.c_str() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogHandler& getLogHandlerInstance()
|
||||
{
|
||||
static LogHandler s_fLogHandler = &defaultLogHandler;
|
||||
return s_fLogHandler;
|
||||
}
|
||||
|
||||
LogHandler getLogHandler()
|
||||
{
|
||||
return getLogHandlerInstance();
|
||||
}
|
||||
|
||||
void setLogHandler(LogHandler fNewHandler)
|
||||
{
|
||||
getLogHandlerInstance() = fNewHandler;
|
||||
}
|
||||
|
||||
void log(const std::string& message, LogLevel logLevel)
|
||||
{
|
||||
LogHandler logHandler = getLogHandler();
|
||||
if(logHandler)
|
||||
{
|
||||
logHandler(message, logLevel);
|
||||
}
|
||||
}
|
||||
|
||||
// Some handy wrappers
|
||||
void logDebug(const std::string& message)
|
||||
{
|
||||
log(message, LogLevels::Debug );
|
||||
}
|
||||
|
||||
void logInfo(const std::string& message)
|
||||
{
|
||||
log(message, LogLevels::Info);
|
||||
}
|
||||
|
||||
void logWarning(const std::string& message)
|
||||
{
|
||||
log(message, LogLevels::Warning);
|
||||
}
|
||||
|
||||
void logError(const std::string& message)
|
||||
{
|
||||
log(message, LogLevels::Error);
|
||||
}
|
||||
|
||||
void logFatal(const std::string& message)
|
||||
{
|
||||
log(message, LogLevels::Fatal);
|
||||
}
|
||||
|
||||
#ifndef POLYVOX_THROW_ENABLED
|
||||
void defaultThrowHandler(std::exception& e, const char* file, int line)
|
||||
{
|
||||
std::stringstream ss; \
|
||||
ss << std::endl << std::endl; \
|
||||
ss << " PolyVox exception thrown!" << std::endl; \
|
||||
ss << " =========================" << std::endl; \
|
||||
ss << " PolyVox has tried to throw an exception but it was built without support" << std::endl; \
|
||||
ss << " for exceptions. In this scenario PolyVox will call a 'throw handler'" << std::endl; \
|
||||
ss << " and this message is being printed by the default throw handler." << std::endl << std::endl; \
|
||||
|
||||
ss << " If you don't want to enable exceptions then you should try to determine why" << std::endl; \
|
||||
ss << " this exception was thrown and make sure it doesn't happen again. If it was" << std::endl; \
|
||||
ss << " due to something like an invalid argument to a function then you should be" << std::endl; \
|
||||
ss << " able to fix it quite easily by validating parameters as appropriate. More" << std::endl; \
|
||||
ss << " complex exception scenarios (out of memory, etc) might be harder to fix and" << std::endl; \
|
||||
ss << " you should replace this default handler with something which is more" << std::endl; \
|
||||
ss << " meaningful to your users." << std::endl << std::endl; \
|
||||
|
||||
ss << " Exception details" << std::endl; \
|
||||
ss << " -----------------" << std::endl; \
|
||||
ss << " Line: " << line << std::endl; \
|
||||
ss << " File: " << file << std::endl; \
|
||||
ss << " Message: " << e.what() << std::endl << std::endl; \
|
||||
logFatal(ss.str()); \
|
||||
|
||||
POLYVOX_HALT(); \
|
||||
}
|
||||
|
||||
ThrowHandler& getThrowHandlerInstance()
|
||||
{
|
||||
static ThrowHandler s_fThrowHandler = &defaultThrowHandler;
|
||||
return s_fThrowHandler;
|
||||
}
|
||||
|
||||
ThrowHandler getThrowHandler()
|
||||
{
|
||||
return getThrowHandlerInstance();
|
||||
}
|
||||
|
||||
void setThrowHandler(ThrowHandler fNewHandler)
|
||||
{
|
||||
getThrowHandlerInstance() = fNewHandler;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -30,10 +30,6 @@ namespace PolyVox
|
||||
//If this is not the case then the output is undefined.
|
||||
uint8_t logBase2(uint32_t uInput)
|
||||
{
|
||||
//Debug mode validation
|
||||
POLYVOX_ASSERT(uInput != 0, "Cannot compute the log of zero.");
|
||||
POLYVOX_ASSERT(isPowerOf2(uInput), "Input must be a power of two in order to compute the log.");
|
||||
|
||||
//Release mode validation
|
||||
if(uInput == 0)
|
||||
{
|
||||
|
@ -78,7 +78,10 @@ namespace PolyVox
|
||||
*/
|
||||
void Region::accumulate(const Region& reg)
|
||||
{
|
||||
POLYVOX_ASSERT(reg.isValid(), "You cannot accumulate an invalid region."); //The result of accumulating an invalid region is not defined.
|
||||
if(!reg.isValid())
|
||||
{
|
||||
POLYVOX_THROW(invalid_operation, "You cannot accumulate an invalid region."); //The result of accumulating an invalid region is not defined.
|
||||
}
|
||||
|
||||
m_iLowerX = ((std::min)(m_iLowerX, reg.getLowerX()));
|
||||
m_iLowerY = ((std::min)(m_iLowerY, reg.getLowerY()));
|
||||
|
Reference in New Issue
Block a user