Merge branch 'feature/optimize-extractors' into develop

This commit is contained in:
David Williams 2014-08-26 21:36:43 +02:00
commit 40a290bfce
19 changed files with 263 additions and 989 deletions

View File

@ -24,7 +24,6 @@ PROJECT(PolyVoxCore)
#Projects source files #Projects source files
SET(CORE_SRC_FILES SET(CORE_SRC_FILES
source/ArraySizes.cpp
source/AStarPathfinder.cpp source/AStarPathfinder.cpp
source/Region.cpp source/Region.cpp
) )
@ -34,8 +33,6 @@ SET(CORE_INC_FILES
include/PolyVoxCore/AmbientOcclusionCalculator.h include/PolyVoxCore/AmbientOcclusionCalculator.h
include/PolyVoxCore/AmbientOcclusionCalculator.inl include/PolyVoxCore/AmbientOcclusionCalculator.inl
include/PolyVoxCore/Array.h include/PolyVoxCore/Array.h
include/PolyVoxCore/Array.inl
include/PolyVoxCore/ArraySizes.h
include/PolyVoxCore/AStarPathfinder.h include/PolyVoxCore/AStarPathfinder.h
include/PolyVoxCore/AStarPathfinder.inl include/PolyVoxCore/AStarPathfinder.inl
include/PolyVoxCore/BaseVolume.h include/PolyVoxCore/BaseVolume.h
@ -108,8 +105,6 @@ SET(IMPL_SRC_FILES
) )
SET(IMPL_INC_FILES SET(IMPL_INC_FILES
include/PolyVoxCore/Impl/ArraySizesImpl.h
include/PolyVoxCore/Impl/ArraySizesImpl.inl
include/PolyVoxCore/Impl/AStarPathfinderImpl.h include/PolyVoxCore/Impl/AStarPathfinderImpl.h
include/PolyVoxCore/Impl/Config.h include/PolyVoxCore/Impl/Config.h
include/PolyVoxCore/Impl/ErrorHandling.h include/PolyVoxCore/Impl/ErrorHandling.h
@ -118,8 +113,6 @@ SET(IMPL_INC_FILES
include/PolyVoxCore/Impl/MinizWrapper.h include/PolyVoxCore/Impl/MinizWrapper.h
include/PolyVoxCore/Impl/RandomUnitVectors.h include/PolyVoxCore/Impl/RandomUnitVectors.h
include/PolyVoxCore/Impl/RandomVectors.h include/PolyVoxCore/Impl/RandomVectors.h
include/PolyVoxCore/Impl/SubArray.h
include/PolyVoxCore/Impl/SubArray.inl
include/PolyVoxCore/Impl/Timer.h include/PolyVoxCore/Impl/Timer.h
include/PolyVoxCore/Impl/TypeDef.h include/PolyVoxCore/Impl/TypeDef.h
include/PolyVoxCore/Impl/Utility.h include/PolyVoxCore/Impl/Utility.h

View File

@ -27,8 +27,6 @@ freely, subject to the following restrictions:
#include "Impl/AStarPathfinderImpl.h" #include "Impl/AStarPathfinderImpl.h"
#include "Impl/TypeDef.h" #include "Impl/TypeDef.h"
#include "PolyVoxCore/Array.h"
#include <functional> #include <functional>
#include <list> #include <list>
#include <stdexcept> //For runtime_error #include <stdexcept> //For runtime_error

View File

@ -128,7 +128,7 @@ namespace PolyVox
POLYVOX_ASSERT((fVisibility >= 0.0f) && (fVisibility <= 1.0f), "Visibility value out of range."); POLYVOX_ASSERT((fVisibility >= 0.0f) && (fVisibility <= 1.0f), "Visibility value out of range.");
} }
(*arrayResult)[z / iRatioZ][y / iRatioY][x / iRatioX] = static_cast<uint8_t>(255.0f * fVisibility); (*arrayResult)(z / iRatioZ, y / iRatioY, x / iRatioX) = static_cast<uint8_t>(255.0f * fVisibility);
} }
} }
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
Copyright (c) 2005-2009 David Williams Copyright (c) 2005-20014 David Williams
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -9,202 +9,185 @@ Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions: freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not 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 claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be in a product, an acknowledgment in the product documentation would be
appreciated but is not required. appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be 2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source 3. This notice may not be removed or altered from any source
distribution. distribution.
*******************************************************************************/ *******************************************************************************/
#ifndef __PolyVox_Array_H__ #ifndef __PolyVox_Array_H__
#define __PolyVox_Array_H__ #define __PolyVox_Array_H__
#include "Impl/SubArray.h" #include <PolyVoxCore/Impl/ErrorHandling.h>
#include "PolyVoxCore/ArraySizes.h" //Not strictly required, but convienient #include <cstdint>
namespace PolyVox namespace PolyVox
{ {
///Provides an efficient implementation of a multidimensional array.
////////////////////////////////////////////////////////////////////////////////
/// While C++ provides one-dimensional arrays as a language feature, it does not
/// provide a simple and intuitive way of working with multidimensional arrays
/// whose sizes are specified at runtime. Such a construct is very useful within
/// the context of PolyVox, and this Array class provides such functionality
/// implemented via templates and partial specialisation.
///
/// The following code snippet illustrates the basic usage of the class by writing
/// a different value into each element:
///
/// \code
/// int width = 5;
/// int height = 10;
/// int depth = 20;
///
/// //Creates a 3D array of integers with dimensions 5x10x20
/// Array<3, int> myArray(ArraySizes(width)(height)(depth));
///
/// int ct = 1;
/// for(int z = 0; z < depth; z++)
/// {
/// for(int y = 0; y < height; y++)
/// {
/// for(int x = 0; x < width; x++)
/// {
/// myArray[x][y][z] = ct;
/// ct++;
/// }
/// }
/// }
/// \endcode
///
/// Although the constructor and resize() functions both take the required dimensions
/// as an array of ints, note that the ArraySizes class can be used to build this
/// inline. This is a more convienient way of specifying these dimensions.
///
/// Note also that this class has a private assignment operator and copy constructor
/// in order to prevent copying. This is because a deep copy is a potentially slow
/// operation and can often be performed inadvertently by functions such as std::swap,
/// while a shallow copy introduces confusion over memory ownership.
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType> template <uint32_t noOfDims, typename ElementType>
class Array class Array
{ {
public: public:
///Constructor
Array<noOfDims, ElementType>();
///Constructor
Array<noOfDims, ElementType>(const uint32_t (&pDimensions)[noOfDims]);
///Destructor
~Array<noOfDims, ElementType>();
///Subarray access Array(uint32_t width)
SubArray<noOfDims-1, ElementType> operator[](uint32_t uIndex); :m_pElements(0)
///Subarray access {
const SubArray<noOfDims-1, ElementType> operator[](uint32_t uIndex) const; static_assert(noOfDims == 1, "This constructor can only be used with a one-dimensional array");
///Gets the total number of elements in this array m_uDimensions[0] = width;
uint32_t getNoOfElements(void) const;
///Gets a pointer to the first element of the array
ElementType* getRawData(void) const;
///Resize the array to the specified dimensions initialize();
void resize(const uint32_t (&pDimensions)[noOfDims]); }
///Swaps the contents of this array with the one specified
void swap(Array<noOfDims, ElementType>& rhs); Array(uint32_t width, uint32_t height)
///Get the size of the Array along the specified dimension :m_pElements(0)
uint32_t getDimension(uint32_t uDimension); {
static_assert(noOfDims == 2, "This constructor can only be used with a two-dimensional array");
m_uDimensions[0] = width;
m_uDimensions[1] = height;
initialize();
}
Array(uint32_t width, uint32_t height, uint32_t depth)
:m_pElements(0)
{
static_assert(noOfDims == 3, "This constructor can only be used with a three-dimensional array");
m_uDimensions[0] = width;
m_uDimensions[1] = height;
m_uDimensions[2] = depth;
initialize();
}
// These are deleted to avoid accidental copying.
Array<noOfDims, ElementType>(const Array<noOfDims, ElementType>&) = delete;
Array<noOfDims, ElementType>& operator=(const Array<noOfDims, ElementType>&) = delete;
~Array()
{
delete[] m_pElements;
}
ElementType& operator()(uint32_t x) const
{
static_assert(noOfDims == 1, "This accessor can only be used with a one-dimensional array");
POLYVOX_ASSERT(x < m_uDimensions[0], "Array access is out-of-range.");
return m_pElements[x];
}
ElementType& operator()(uint32_t x, uint32_t y) const
{
static_assert(noOfDims == 2, "This accessor can only be used with a two-dimensional array");
POLYVOX_ASSERT(x < m_uDimensions[0] && y < m_uDimensions[1], "Array access is out-of-range.");
return m_pElements[y * m_uDimensions[0] + x];
}
ElementType& operator()(uint32_t x, uint32_t y, uint32_t z) const
{
static_assert(noOfDims == 3, "This accessor can only be used with a three-dimensional array");
POLYVOX_ASSERT(x < m_uDimensions[0] && y < m_uDimensions[1] && z < m_uDimensions[2], "Array access is out-of-range.");
return m_pElements[z * m_uDimensions[0] * m_uDimensions[1] + y * m_uDimensions[0] + x];
}
uint32_t getDimension(uint32_t dimension)
{
return m_uDimensions[dimension];
}
ElementType* getRawData()
{
return m_pElements;
}
uint32_t getNoOfElements()
{
return m_uNoOfElements;
}
void swap(Array& other)
{
ElementType* temp = other.m_pElements;
other.m_pElements = m_pElements;
m_pElements = temp;
}
private: private:
Array<noOfDims, ElementType>(const Array<noOfDims, ElementType>& rhs);
Array<noOfDims, ElementType>& operator=(const Array<noOfDims, ElementType>& rhs); void initialize(void)
{
// Calculate the total number of elements in the array.
m_uNoOfElements = 1;
for (uint32_t i = 0; i < noOfDims; i++)
{
m_uNoOfElements *= m_uDimensions[i];
}
m_pElements = new ElementType[m_uNoOfElements];
}
void deallocate(void); uint32_t m_uDimensions[noOfDims];
uint32_t * m_pDimensions;
uint32_t * m_pOffsets;
uint32_t m_uNoOfElements; uint32_t m_uNoOfElements;
ElementType * m_pElements; ElementType* m_pElements;
}; };
template <typename ElementType>
class Array<1, ElementType>
{
public:
Array<1, ElementType>();
Array<1, ElementType>(const uint32_t (&pDimensions)[1]);
~Array<1, ElementType>();
ElementType& operator[] (uint32_t uIndex);
const ElementType& operator[] (uint32_t uIndex) const;
uint32_t getNoOfElements(void) const;
ElementType* getRawData(void) const;
void resize(const uint32_t (&pDimensions)[1]);
void swap(Array<1, ElementType>& rhs);
private:
Array<1, ElementType>(const Array<1, ElementType>& rhs);
Array<1, ElementType>& operator=(const Array<1, ElementType>& rhs);
void deallocate(void);
uint32_t * m_pDimensions;
ElementType * m_pElements;
};
template <typename ElementType>
class Array<0, ElementType>
{
//Zero dimensional array is meaningless.
};
//Some handy typedefs
///A 1D Array of floats. ///A 1D Array of floats.
typedef Array<1,float> Array1DFloat; typedef Array<1, float> Array1DFloat;
///A 1D Array of doubles. ///A 1D Array of doubles.
typedef Array<1,double> Array1DDouble; typedef Array<1, double> Array1DDouble;
///A 1D Array of signed 8-bit values. ///A 1D Array of signed 8-bit values.
typedef Array<1,int8_t> Array1DInt8; typedef Array<1, int8_t> Array1DInt8;
///A 1D Array of unsigned 8-bit values. ///A 1D Array of unsigned 8-bit values.
typedef Array<1,uint8_t> Array1DUint8; typedef Array<1, uint8_t> Array1DUint8;
///A 1D Array of signed 16-bit values. ///A 1D Array of signed 16-bit values.
typedef Array<1,int16_t> Array1DInt16; typedef Array<1, int16_t> Array1DInt16;
///A 1D Array of unsigned 16-bit values. ///A 1D Array of unsigned 16-bit values.
typedef Array<1,uint16_t> Array1DUint16; typedef Array<1, uint16_t> Array1DUint16;
///A 1D Array of signed 32-bit values. ///A 1D Array of signed 32-bit values.
typedef Array<1,int32_t> Array1DInt32; typedef Array<1, int32_t> Array1DInt32;
///A 1D Array of unsigned 32-bit values. ///A 1D Array of unsigned 32-bit values.
typedef Array<1,uint32_t> Array1DUint32; typedef Array<1, uint32_t> Array1DUint32;
///A 2D Array of floats. ///A 2D Array of floats.
typedef Array<2,float> Array2DFloat; typedef Array<2, float> Array2DFloat;
///A 2D Array of doubles. ///A 2D Array of doubles.
typedef Array<2,double> Array2DDouble; typedef Array<2, double> Array2DDouble;
///A 2D Array of signed 8-bit values. ///A 2D Array of signed 8-bit values.
typedef Array<2,int8_t> Array2DInt8; typedef Array<2, int8_t> Array2DInt8;
///A 2D Array of unsigned 8-bit values. ///A 2D Array of unsigned 8-bit values.
typedef Array<2,uint8_t> Array2DUint8; typedef Array<2, uint8_t> Array2DUint8;
///A 2D Array of signed 16-bit values. ///A 2D Array of signed 16-bit values.
typedef Array<2,int16_t> Array2DInt16; typedef Array<2, int16_t> Array2DInt16;
///A 2D Array of unsigned 16-bit values. ///A 2D Array of unsigned 16-bit values.
typedef Array<2,uint16_t> Array2DUint16; typedef Array<2, uint16_t> Array2DUint16;
///A 2D Array of signed 32-bit values. ///A 2D Array of signed 32-bit values.
typedef Array<2,int32_t> Array2DInt32; typedef Array<2, int32_t> Array2DInt32;
///A 2D Array of unsigned 32-bit values. ///A 2D Array of unsigned 32-bit values.
typedef Array<2,uint32_t> Array2DUint32; typedef Array<2, uint32_t> Array2DUint32;
///A 3D Array of floats. ///A 3D Array of floats.
typedef Array<3,float> Array3DFloat; typedef Array<3, float> Array3DFloat;
///A 3D Array of doubles. ///A 3D Array of doubles.
typedef Array<3,double> Array3DDouble; typedef Array<3, double> Array3DDouble;
///A 3D Array of signed 8-bit values. ///A 3D Array of signed 8-bit values.
typedef Array<3,int8_t> Array3DInt8; typedef Array<3, int8_t> Array3DInt8;
///A 3D Array of unsigned 8-bit values. ///A 3D Array of unsigned 8-bit values.
typedef Array<3,uint8_t> Array3DUint8; typedef Array<3, uint8_t> Array3DUint8;
///A 3D Array of signed 16-bit values. ///A 3D Array of signed 16-bit values.
typedef Array<3,int16_t> Array3DInt16; typedef Array<3, int16_t> Array3DInt16;
///A 3D Array of unsigned 16-bit values. ///A 3D Array of unsigned 16-bit values.
typedef Array<3,uint16_t> Array3DUint16; typedef Array<3, uint16_t> Array3DUint16;
///A 3D Array of signed 32-bit values. ///A 3D Array of signed 32-bit values.
typedef Array<3,int32_t> Array3DInt32; typedef Array<3, int32_t> Array3DInt32;
///A 3D Array of unsigned 32-bit values. ///A 3D Array of unsigned 32-bit values.
typedef Array<3,uint32_t> Array3DUint32; typedef Array<3, uint32_t> Array3DUint32;
}//namespace PolyVox }
#include "PolyVoxCore/Array.inl" #endif //__PolyVox_Array_H__
#endif

View File

@ -1,335 +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.
*******************************************************************************/
namespace PolyVox
{
////////////////////////////////////////////////////////////////////////////////
/// Creates an empty array with no elements. You will have to call resize() on this
/// array before it can be used.
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
Array<noOfDims, ElementType>::Array()
:m_pDimensions(0)
,m_pOffsets(0)
,m_uNoOfElements(0)
,m_pElements(0)
{
}
////////////////////////////////////////////////////////////////////////////////
/// Creates an array with the specified dimensions.
/// \param pDimensions The dimensions of the array. You can also use the ArraySizes
/// class to construct this more easily.
/// \sa ArraySizes
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
Array<noOfDims, ElementType>::Array(const uint32_t (&pDimensions)[noOfDims])
:m_pDimensions(0)
,m_pOffsets(0)
,m_uNoOfElements(0)
,m_pElements(0)
{
resize(pDimensions);
}
////////////////////////////////////////////////////////////////////////////////
/// Destroys the array and releases all owned memory.
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
Array<noOfDims, ElementType>::~Array()
{
deallocate();
}
////////////////////////////////////////////////////////////////////////////////
/// An N-dimensional array can be conceptually consists of N subarrays each of which
/// has N-1 dimensions. For example, a 3D array conceptually consists of three 2D
/// arrays. This operator is used to access the subarray at the specified index.
/// Crucially, the subarray defines a similar operator allowing them to be chained
/// together to convieniently access a particular element.
/// \param uIndex The zero-based index of the subarray to retrieve.
/// \return The requested SubArray
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex)
{
POLYVOX_THROW_IF(uIndex >= m_pDimensions[0], 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);
}
////////////////////////////////////////////////////////////////////////////////
/// An N-dimensional array can be conceptually consists of N subarrays each of which
/// has N-1 dimensions. For example, a 3D array conceptually consists of three 2D
/// arrays. This operator is used to access the subarray at the specified index.
/// Crucially, the subarray defines a similar operator allowing them to be chained
/// together to convieniently access a particular element.
/// \param uIndex The zero-based index of the subarray to retrieve.
/// \return The requested SubArray
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
const SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex) const
{
POLYVOX_THROW_IF(uIndex >= m_pDimensions[0], 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);
}
////////////////////////////////////////////////////////////////////////////////
/// \return The number of elements in the array.
/// \sa getRawData()
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
uint32_t Array<noOfDims, ElementType>::getNoOfElements(void) const
{
return m_uNoOfElements;
}
////////////////////////////////////////////////////////////////////////////////
/// Sometimes it is useful to directly manipulate the underlying array without
/// going through this classes interface. Although this does not honour the principle
/// of encapsulation it can be done safely if you are careful and can sometimes be
/// useful. Use getNoOfElements() to determine how far you can safely write.
/// \return A pointer to the first element of the array
/// \sa getNoOfElements()
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
ElementType* Array<noOfDims, ElementType>::getRawData(void) const
{
return m_pElements;
}
////////////////////////////////////////////////////////////////////////////////
/// Please note that the existing contents of the array will be lost.
/// \param pDimensions The new dimensions of the array. You can also use the
/// ArraySizes class to specify this more easily.
/// \sa ArraySizes
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
void Array<noOfDims, ElementType>::resize(const uint32_t (&pDimensions)[noOfDims])
{
deallocate();
m_pDimensions = new uint32_t[noOfDims];
m_pOffsets = new uint32_t[noOfDims];
// Calculate all the information you need to use the array
m_uNoOfElements = 1;
for (uint32_t i = 0; i<noOfDims; i++)
{
POLYVOX_THROW_IF(pDimensions[i] == 0, std::out_of_range, "Invalid array dimension");
m_uNoOfElements *= pDimensions[i];
m_pDimensions[i] = pDimensions[i];
m_pOffsets[i] = 1;
for (uint32_t k=noOfDims-1; k>i; k--)
{
m_pOffsets[i] *= pDimensions[k];
}
}
// Allocate new elements, let exception propagate
m_pElements = new ElementType[m_uNoOfElements];
}
////////////////////////////////////////////////////////////////////////////////
/// Because this class does not have a public assignment operator or copy constructor
/// it cannot be used with the STL swap() function. This function provides an efficient
/// implementation of that feature.
/// \param rhs The array to swap this object with.
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
void Array<noOfDims, ElementType>::swap(Array<noOfDims, ElementType>& rhs)
{
//Implement this function without temporary 'Array'
//objects, as the destructors will free the memory...
uint32_t* m_pTempDimensions = m_pDimensions;
uint32_t* m_pTempOffsets = m_pOffsets;
uint32_t m_uTempNoOfElements = m_uNoOfElements;
ElementType* m_pTempElements = m_pElements;
m_pDimensions = rhs.m_pDimensions;
m_pOffsets = rhs.m_pOffsets;
m_uNoOfElements = rhs.m_uNoOfElements;
m_pElements = rhs.m_pElements;
rhs.m_pDimensions = m_pTempDimensions;
rhs.m_pOffsets = m_pTempOffsets;
rhs.m_uNoOfElements = m_uTempNoOfElements;
rhs.m_pElements = m_pTempElements;
}
////////////////////////////////////////////////////////////////////////////////
/// \param uDimension The dimension to get the size of.
////////////////////////////////////////////////////////////////////////////////
template <uint32_t noOfDims, typename ElementType>
uint32_t Array<noOfDims, ElementType>::getDimension(uint32_t uDimension)
{
POLYVOX_THROW_IF(uDimension >= noOfDims, std::out_of_range, "Array dimension out of range");
return m_pDimensions[uDimension];
}
template <uint32_t noOfDims, typename ElementType>
Array<noOfDims, ElementType>::Array(const Array<noOfDims, ElementType>& rhs)
:m_pElements(0)
,m_pDimensions(0)
,m_pOffsets(0)
,m_uNoOfElements(0)
{
//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_THROW(not_implemented, "This function is not implemented and should never be called!");
return *this;
}
template <uint32_t noOfDims, typename ElementType>
void Array<noOfDims, ElementType>::deallocate(void)
{
delete[] m_pDimensions;
m_pDimensions = 0;
delete[] m_pOffsets;
m_pOffsets = 0;
delete[] m_pElements;
m_pElements = 0;
m_uNoOfElements = 0;
}
//****************************************************************************//
// One dimensional specialisation begins here //
//****************************************************************************//
template <typename ElementType>
Array<1, ElementType>::Array()
: m_pElements(0)
,m_pDimensions(0)
{
}
template <typename ElementType>
Array<1, ElementType>::Array(const uint32_t (&pDimensions)[1])
: m_pElements(0)
,m_pDimensions(0)
{
resize(pDimensions);
}
template <typename ElementType>
Array<1, ElementType>::~Array()
{
deallocate();
}
template <typename ElementType>
ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex)
{
POLYVOX_THROW_IF(uIndex >= m_pDimensions[0], 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_THROW_IF(uIndex >= m_pDimensions[0], std::out_of_range, "Array index out of range");
return m_pElements[uIndex];
}
template <typename ElementType>
uint32_t Array<1, ElementType>::getNoOfElements(void) const
{
return m_pDimensions[0];
}
template <typename ElementType>
ElementType* Array<1, ElementType>::getRawData(void) const
{
return m_pElements;
}
template <typename ElementType>
void Array<1, ElementType>::resize(const uint32_t (&pDimensions)[1])
{
deallocate();
m_pDimensions = new uint32_t[1];
m_pDimensions[0] = pDimensions[0];
// Allocate new elements, let exception propagate
m_pElements = new ElementType[m_pDimensions[0]];
}
template <typename ElementType>
void Array<1, ElementType>::swap(Array<1, ElementType>& rhs)
{
//Implement this function without temporary 'Array'
//objects, as the destructors will free the memory...
uint32_t* m_pTempDimensions = m_pDimensions;
ElementType* m_pTempElements = m_pElements;
m_pDimensions = rhs.m_pDimensions;
m_pElements = rhs.m_pElements;
rhs.m_pDimensions = m_pTempDimensions;
rhs.m_pElements = m_pTempElements;
}
template <typename ElementType>
Array<1, ElementType>::Array(const Array<1, ElementType>& rhs)
: m_pElements(0)
,m_pDimensions(0)
{
//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_THROW(not_implemented, "This function is not implemented and should never be called!");
return *this;
}
template <typename ElementType>
void Array<1, ElementType>::deallocate(void)
{
delete[] m_pDimensions;
m_pDimensions = 0;
delete[] m_pElements;
m_pElements = 0;
}
}//namespace PolyVox

View File

@ -1,77 +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_ArraySizes_H__
#define __PolyVox_ArraySizes_H__
#include "Impl/ArraySizesImpl.h"
#include "Impl/TypeDef.h"
namespace PolyVox
{
///The ArraySizes class provide a convienient way to specify the dimensions of an Array.
////////////////////////////////////////////////////////////////////////////////
/// The Array class requires an array of integers to be passed to the constructor
/// to specify the dimensions of the Array to be built. C++ does not allow this to
/// be done in place, and so it typically requires an extra line of code - something
/// like this:
///
/// \code
/// uint32_t dimensions[3] = {10, 20, 30}; // Array dimensions
/// Array<3,float> array(dimensions);
/// \endcode
///
/// The ArraySizes class can be constructed in place, and also provides implicit
/// conversion to an array of integers. Hence it is now possible to declare the
/// above Array as follows:
///
/// \code
/// Array<3,float> array(ArraySizes(10)(20)(30));
/// \endcode
///
/// Usage of this class is therefore very simple, although the template code
/// behind it may appear complex. For reference, it is based upon the article here:
/// http://www.drdobbs.com/cpp/184401319/
////////////////////////////////////////////////////////////////////////////////
class POLYVOX_API ArraySizes
{
typedef const uint32_t (&UIntArray1)[1];
public:
/// Constructor
explicit ArraySizes(uint32_t uSize);
/// Duplicates this object but with an extra dimension
ArraySizesImpl<2> operator () (uint32_t uSize);
/// Converts this object to an array of integers
operator UIntArray1 () const;
private:
// This class is only one dimensional. Higher dimensions
// are implemented via the ArraySizesImpl class.
uint32_t m_pSizes[1];
};
}//namespace PolyVox
#endif //__PolyVox_ArraySizes_H__

View File

@ -43,6 +43,8 @@ namespace PolyVox
,m_bMergeQuads(bMergeQuads) ,m_bMergeQuads(bMergeQuads)
,m_eWrapMode(eWrapMode) ,m_eWrapMode(eWrapMode)
,m_tBorderValue(tBorderValue) ,m_tBorderValue(tBorderValue)
,m_previousSliceVertices(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2, m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2, MaxVerticesPerPosition)
,m_currentSliceVertices(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2, m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2, MaxVerticesPerPosition)
{ {
m_funcIsQuadNeededCallback = isQuadNeeded; m_funcIsQuadNeededCallback = isQuadNeeded;
@ -59,12 +61,12 @@ namespace PolyVox
Timer timer; Timer timer;
m_meshCurrent->clear(); m_meshCurrent->clear();
uint32_t uArrayWidth = m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2; //uint32_t uArrayWidth = m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2;
uint32_t uArrayHeight = m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2; //uint32_t uArrayHeight = m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2;
uint32_t arraySize[3]= {uArrayWidth, uArrayHeight, MaxVerticesPerPosition}; //uint32_t arraySize[3]= {uArrayWidth, uArrayHeight, MaxVerticesPerPosition};
m_previousSliceVertices.resize(arraySize); //m_previousSliceVertices.resize(arraySize);
m_currentSliceVertices.resize(arraySize); //m_currentSliceVertices.resize(arraySize);
memset(m_previousSliceVertices.getRawData(), 0xff, m_previousSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial)); memset(m_previousSliceVertices.getRawData(), 0xff, m_previousSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial));
memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial)); memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial));
@ -209,7 +211,7 @@ namespace PolyVox
{ {
for(uint32_t ct = 0; ct < MaxVerticesPerPosition; ct++) for(uint32_t ct = 0; ct < MaxVerticesPerPosition; ct++)
{ {
IndexAndMaterial& rEntry = existingVertices[uX][uY][ct]; IndexAndMaterial& rEntry = existingVertices(uX, uY, ct);
if(rEntry.iIndex == -1) if(rEntry.iIndex == -1)
{ {

View File

@ -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_ArraySizesImpl_H__
#define __PolyVox_ArraySizesImpl_H__
#include "PolyVoxCore/Impl/TypeDef.h"
#include <cstdint>
namespace PolyVox
{
/*
This class provides the implementation details behind ArraySizes. It is actually
quite similar to ArraySizes, but an important difference is that it is templatised
whereas ArraySizes is not. This allows us to use a recursive template pattern without
exposing the use of templates to the user.
It is based on the following article: http://www.drdobbs.com/cpp/184401319
*/
template <uint32_t N>
class ArraySizesImpl
{
typedef const uint32_t (&UIntArrayN)[N];
friend class ArraySizes;
friend class ArraySizesImpl<N-1>;
public:
ArraySizesImpl<N+1> operator () (uint32_t uSize);
operator UIntArrayN () const;
private:
ArraySizesImpl(const uint32_t (&pSizes)[N-1], uint32_t uSize);
uint32_t m_pSizes[N];
};
}//namespace PolyVox
#include "PolyVoxCore/Impl/ArraySizesImpl.inl"
#endif //__PolyVox_ArraySizesImpl_H__

View File

@ -1,46 +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.
*******************************************************************************/
#include <algorithm>
namespace PolyVox
{
template <uint32_t N>
ArraySizesImpl<N+1> ArraySizesImpl<N>::operator () (uint32_t uSize)
{
return ArraySizesImpl<N+1>(m_pSizes, uSize);
}
template <uint32_t N>
ArraySizesImpl<N>::operator UIntArrayN () const
{
return m_pSizes;
}
template <uint32_t N>
ArraySizesImpl<N>::ArraySizesImpl(const uint32_t (&pSizes)[N-1], uint32_t uSize)
{
std::copy(&pSizes[0],&pSizes[N-1],m_pSizes);
m_pSizes[N-1]=uSize;
}
}//namespace PolyVox

View File

@ -1,90 +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_SubArray_H__
#define __PolyVox_SubArray_H__
#include "PolyVoxCore/Impl/TypeDef.h"
#include <cstdint>
namespace PolyVox
{
template <uint32_t noOfDims, typename ElementType> class Array;
/*
This class forms part of the implementation of the Array class. The operator[]
return a SubArray of the next size down, so that multiple []'s can be chained
together. It is a seperate class from Array so that it can have a reduced interface,
and also so that it never takes ownership of the memory to which it points.
It is based on the following article: http://www.drdobbs.com/cpp/184401319
*/
template <uint32_t noOfDims, typename ElementType>
class SubArray
{
friend class Array<noOfDims+1, ElementType>;
friend class SubArray<noOfDims+1, ElementType>;
public:
SubArray<noOfDims-1, ElementType> operator [](uint32_t uIndex);
const SubArray<noOfDims-1, ElementType> operator [](uint32_t uIndex) const;
private:
SubArray<noOfDims, ElementType>(ElementType * pElements, uint32_t * pDimensions, uint32_t * pOffsets);
uint32_t * m_pDimensions;
uint32_t * m_pOffsets;
uint32_t m_uNoOfElements;
ElementType * m_pElements;
};
template <typename ElementType>
class SubArray<1, ElementType>
{
friend class Array<2, ElementType>;
friend class SubArray<2, ElementType>;
public:
ElementType & operator [] (uint32_t uIndex);
const ElementType & operator [] (uint32_t uIndex) const;
private:
SubArray<1, ElementType>(ElementType * pElements, uint32_t * pDimensions, uint32_t * /*pOffsets*/);
uint32_t * m_pDimensions;
ElementType * m_pElements;
};
template <typename ElementType>
class SubArray<0, ElementType>
{
//Zero dimensional subarray is meaningless.
};
}//namespace PolyVox
#include "PolyVoxCore/Impl/SubArray.inl"
#endif //__PolyVox_SubArray_H__

View File

@ -1,92 +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.
*******************************************************************************/
#include "PolyVoxCore/Impl/ErrorHandling.h"
namespace PolyVox
{
template <uint32_t noOfDims, typename ElementType>
SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex)
{
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);
}
template <uint32_t noOfDims, typename ElementType>
const SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex) const
{
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);
}
template <uint32_t noOfDims, typename ElementType>
SubArray<noOfDims, ElementType>::SubArray(ElementType * pElements, uint32_t * pDimensions, uint32_t * pOffsets)
:m_pDimensions(pDimensions)
,m_pOffsets(pOffsets)
,m_uNoOfElements(0)
,m_pElements(pElements)
{
}
template <typename ElementType>
ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex)
{
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
{
if(uIndex >= m_pDimensions[0])
{
POLYVOX_THROW(std::out_of_range, "Array index out of range");
}
return m_pElements[uIndex];
}
template <typename ElementType>
SubArray<1, ElementType>::SubArray(ElementType * pElements, uint32_t * pDimensions, uint32_t * /*pOffsets*/)
:m_pDimensions(pDimensions)
,m_pElements(pElements)
{
}
}//namespace PolyVox

View File

@ -53,15 +53,15 @@ namespace PolyVox
const uint32_t arraySizes[2]= {uArrayWidth, uArrayHeight}; // Array dimensions const uint32_t arraySizes[2]= {uArrayWidth, uArrayHeight}; // Array dimensions
//For edge indices //For edge indices
Array2DInt32 m_pPreviousVertexIndicesX(arraySizes); Array2DInt32 m_pPreviousVertexIndicesX(uArrayWidth, uArrayHeight);
Array2DInt32 m_pPreviousVertexIndicesY(arraySizes); Array2DInt32 m_pPreviousVertexIndicesY(uArrayWidth, uArrayHeight);
Array2DInt32 m_pPreviousVertexIndicesZ(arraySizes); Array2DInt32 m_pPreviousVertexIndicesZ(uArrayWidth, uArrayHeight);
Array2DInt32 m_pCurrentVertexIndicesX(arraySizes); Array2DInt32 m_pCurrentVertexIndicesX(uArrayWidth, uArrayHeight);
Array2DInt32 m_pCurrentVertexIndicesY(arraySizes); Array2DInt32 m_pCurrentVertexIndicesY(uArrayWidth, uArrayHeight);
Array2DInt32 m_pCurrentVertexIndicesZ(arraySizes); Array2DInt32 m_pCurrentVertexIndicesZ(uArrayWidth, uArrayHeight);
Array2DUint8 pPreviousBitmask(arraySizes); Array2DUint8 pPreviousBitmask(uArrayWidth, uArrayHeight);
Array2DUint8 pCurrentBitmask(arraySizes); Array2DUint8 pCurrentBitmask(uArrayWidth, uArrayHeight);
//Create a region corresponding to the first slice //Create a region corresponding to the first slice
m_regSlicePrevious = m_regSizeInVoxels; m_regSlicePrevious = m_regSizeInVoxels;
@ -220,16 +220,16 @@ namespace PolyVox
v111 = m_sampVolume.peekVoxel1px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz();
//z //z
uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; uint8_t iPreviousCubeIndexZ = pPreviousBitmask(uXRegSpace, uYRegSpace);
iPreviousCubeIndexZ >>= 4; iPreviousCubeIndexZ >>= 4;
//y //y
uint8_t iPreviousCubeIndexY = pCurrentBitmask[uXRegSpace][uYRegSpace-1]; uint8_t iPreviousCubeIndexY = pCurrentBitmask(uXRegSpace, uYRegSpace - 1);
iPreviousCubeIndexY &= 192; //192 = 128 + 64 iPreviousCubeIndexY &= 192; //192 = 128 + 64
iPreviousCubeIndexY >>= 2; iPreviousCubeIndexY >>= 2;
//x //x
uint8_t iPreviousCubeIndexX = pCurrentBitmask[uXRegSpace-1][uYRegSpace]; uint8_t iPreviousCubeIndexX = pCurrentBitmask(uXRegSpace - 1, uYRegSpace);
iPreviousCubeIndexX &= 128; iPreviousCubeIndexX &= 128;
iPreviousCubeIndexX >>= 1; iPreviousCubeIndexX >>= 1;
@ -243,11 +243,11 @@ namespace PolyVox
v111 = m_sampVolume.peekVoxel1px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz();
//z //z
uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; uint8_t iPreviousCubeIndexZ = pPreviousBitmask(uXRegSpace, uYRegSpace);
iPreviousCubeIndexZ >>= 4; iPreviousCubeIndexZ >>= 4;
//y //y
uint8_t iPreviousCubeIndexY = pCurrentBitmask[uXRegSpace][uYRegSpace-1]; uint8_t iPreviousCubeIndexY = pCurrentBitmask(uXRegSpace, uYRegSpace - 1);
iPreviousCubeIndexY &= 192; //192 = 128 + 64 iPreviousCubeIndexY &= 192; //192 = 128 + 64
iPreviousCubeIndexY >>= 2; iPreviousCubeIndexY >>= 2;
@ -265,11 +265,11 @@ namespace PolyVox
v111 = m_sampVolume.peekVoxel1px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz();
//z //z
uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; uint8_t iPreviousCubeIndexZ = pPreviousBitmask(uXRegSpace, uYRegSpace);
iPreviousCubeIndexZ >>= 4; iPreviousCubeIndexZ >>= 4;
//x //x
uint8_t iPreviousCubeIndexX = pCurrentBitmask[uXRegSpace-1][uYRegSpace]; uint8_t iPreviousCubeIndexX = pCurrentBitmask(uXRegSpace - 1, uYRegSpace);
iPreviousCubeIndexX &= 160; //160 = 128+32 iPreviousCubeIndexX &= 160; //160 = 128+32
iPreviousCubeIndexX >>= 1; iPreviousCubeIndexX >>= 1;
@ -286,7 +286,7 @@ namespace PolyVox
v111 = m_sampVolume.peekVoxel1px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz();
//z //z
uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; uint8_t iPreviousCubeIndexZ = pPreviousBitmask(uXRegSpace, uYRegSpace);
iCubeIndex = iPreviousCubeIndexZ >> 4; iCubeIndex = iPreviousCubeIndexZ >> 4;
if (m_controller.convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; if (m_controller.convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16;
@ -306,12 +306,12 @@ namespace PolyVox
v111 = m_sampVolume.peekVoxel1px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz();
//y //y
uint8_t iPreviousCubeIndexY = pCurrentBitmask[uXRegSpace][uYRegSpace-1]; uint8_t iPreviousCubeIndexY = pCurrentBitmask(uXRegSpace, uYRegSpace - 1);
iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 iPreviousCubeIndexY &= 204; //204 = 128+64+8+4
iPreviousCubeIndexY >>= 2; iPreviousCubeIndexY >>= 2;
//x //x
uint8_t iPreviousCubeIndexX = pCurrentBitmask[uXRegSpace-1][uYRegSpace]; uint8_t iPreviousCubeIndexX = pCurrentBitmask(uXRegSpace - 1, uYRegSpace);
iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 iPreviousCubeIndexX &= 170; //170 = 128+32+8+2
iPreviousCubeIndexX >>= 1; iPreviousCubeIndexX >>= 1;
@ -329,7 +329,7 @@ namespace PolyVox
v111 = m_sampVolume.peekVoxel1px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz();
//y //y
uint8_t iPreviousCubeIndexY = pCurrentBitmask[uXRegSpace][uYRegSpace-1]; uint8_t iPreviousCubeIndexY = pCurrentBitmask(uXRegSpace, uYRegSpace - 1);
iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 iPreviousCubeIndexY &= 204; //204 = 128+64+8+4
iPreviousCubeIndexY >>= 2; iPreviousCubeIndexY >>= 2;
@ -352,7 +352,7 @@ namespace PolyVox
v111 = m_sampVolume.peekVoxel1px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz();
//x //x
uint8_t iPreviousCubeIndexX = pCurrentBitmask[uXRegSpace-1][uYRegSpace]; uint8_t iPreviousCubeIndexX = pCurrentBitmask(uXRegSpace - 1, uYRegSpace);
iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 iPreviousCubeIndexX &= 170; //170 = 128+32+8+2
iPreviousCubeIndexX >>= 1; iPreviousCubeIndexX >>= 1;
@ -388,7 +388,7 @@ namespace PolyVox
} }
//Save the bitmask //Save the bitmask
pCurrentBitmask[uXRegSpace][uYRegSpace] = iCubeIndex; pCurrentBitmask(uXRegSpace, uYRegSpace) = iCubeIndex;
if(edgeTable[iCubeIndex] != 0) if(edgeTable[iCubeIndex] != 0)
{ {
@ -415,7 +415,7 @@ namespace PolyVox
const uint32_t uXRegSpace = iXVolSpace - m_regSizeInVoxels.getLowerX(); const uint32_t uXRegSpace = iXVolSpace - m_regSizeInVoxels.getLowerX();
//Determine the index into the edge table which tells us which vertices are inside of the surface //Determine the index into the edge table which tells us which vertices are inside of the surface
const uint8_t iCubeIndex = pCurrentBitmask[uXRegSpace][uYRegSpace]; const uint8_t iCubeIndex = pCurrentBitmask(uXRegSpace, uYRegSpace);
/* Cube is entirely in/out of the surface */ /* Cube is entirely in/out of the surface */
if (edgeTable[iCubeIndex] == 0) if (edgeTable[iCubeIndex] == 0)
@ -461,7 +461,7 @@ namespace PolyVox
surfaceVertex.data = uMaterial; surfaceVertex.data = uMaterial;
const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
m_pCurrentVertexIndicesX[iXVolSpace - m_regSizeInVoxels.getLowerX()][iYVolSpace - m_regSizeInVoxels.getLowerY()] = uLastVertexIndex; m_pCurrentVertexIndicesX(iXVolSpace - m_regSizeInVoxels.getLowerX(), iYVolSpace - m_regSizeInVoxels.getLowerY()) = uLastVertexIndex;
m_sampVolume.moveNegativeX(); m_sampVolume.moveNegativeX();
} }
@ -495,7 +495,7 @@ namespace PolyVox
surfaceVertex.data = uMaterial; surfaceVertex.data = uMaterial;
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
m_pCurrentVertexIndicesY[iXVolSpace - m_regSizeInVoxels.getLowerX()][iYVolSpace - m_regSizeInVoxels.getLowerY()] = uLastVertexIndex; m_pCurrentVertexIndicesY(iXVolSpace - m_regSizeInVoxels.getLowerX(), iYVolSpace - m_regSizeInVoxels.getLowerY()) = uLastVertexIndex;
m_sampVolume.moveNegativeY(); m_sampVolume.moveNegativeY();
} }
@ -528,7 +528,7 @@ namespace PolyVox
surfaceVertex.data = uMaterial; surfaceVertex.data = uMaterial;
const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
m_pCurrentVertexIndicesZ[iXVolSpace - m_regSizeInVoxels.getLowerX()][iYVolSpace - m_regSizeInVoxels.getLowerY()] = uLastVertexIndex; m_pCurrentVertexIndicesZ(iXVolSpace - m_regSizeInVoxels.getLowerX(), iYVolSpace - m_regSizeInVoxels.getLowerY()) = uLastVertexIndex;
m_sampVolume.moveNegativeZ(); m_sampVolume.moveNegativeZ();
} }
@ -563,7 +563,7 @@ namespace PolyVox
const uint32_t uYRegSpace = m_sampVolume.getPosition().getY() - m_regSizeInVoxels.getLowerY(); const uint32_t uYRegSpace = m_sampVolume.getPosition().getY() - m_regSizeInVoxels.getLowerY();
//Determine the index into the edge table which tells us which vertices are inside of the surface //Determine the index into the edge table which tells us which vertices are inside of the surface
const uint8_t iCubeIndex = pPreviousBitmask[uXRegSpace][uYRegSpace]; const uint8_t iCubeIndex = pPreviousBitmask(uXRegSpace, uYRegSpace);
/* Cube is entirely in/out of the surface */ /* Cube is entirely in/out of the surface */
if (edgeTable[iCubeIndex] == 0) if (edgeTable[iCubeIndex] == 0)
@ -574,51 +574,51 @@ namespace PolyVox
/* Find the vertices where the surface intersects the cube */ /* Find the vertices where the surface intersects the cube */
if (edgeTable[iCubeIndex] & 1) if (edgeTable[iCubeIndex] & 1)
{ {
indlist[0] = m_pPreviousVertexIndicesX[uXRegSpace][uYRegSpace]; indlist[0] = m_pPreviousVertexIndicesX(uXRegSpace, uYRegSpace);
} }
if (edgeTable[iCubeIndex] & 2) if (edgeTable[iCubeIndex] & 2)
{ {
indlist[1] = m_pPreviousVertexIndicesY[uXRegSpace+1][uYRegSpace]; indlist[1] = m_pPreviousVertexIndicesY(uXRegSpace + 1, uYRegSpace);
} }
if (edgeTable[iCubeIndex] & 4) if (edgeTable[iCubeIndex] & 4)
{ {
indlist[2] = m_pPreviousVertexIndicesX[uXRegSpace][uYRegSpace+1]; indlist[2] = m_pPreviousVertexIndicesX(uXRegSpace, uYRegSpace + 1);
} }
if (edgeTable[iCubeIndex] & 8) if (edgeTable[iCubeIndex] & 8)
{ {
indlist[3] = m_pPreviousVertexIndicesY[uXRegSpace][uYRegSpace]; indlist[3] = m_pPreviousVertexIndicesY(uXRegSpace, uYRegSpace);
} }
if (edgeTable[iCubeIndex] & 16) if (edgeTable[iCubeIndex] & 16)
{ {
indlist[4] = m_pCurrentVertexIndicesX[uXRegSpace][uYRegSpace]; indlist[4] = m_pCurrentVertexIndicesX(uXRegSpace, uYRegSpace);
} }
if (edgeTable[iCubeIndex] & 32) if (edgeTable[iCubeIndex] & 32)
{ {
indlist[5] = m_pCurrentVertexIndicesY[uXRegSpace+1][uYRegSpace]; indlist[5] = m_pCurrentVertexIndicesY(uXRegSpace + 1, uYRegSpace);
} }
if (edgeTable[iCubeIndex] & 64) if (edgeTable[iCubeIndex] & 64)
{ {
indlist[6] = m_pCurrentVertexIndicesX[uXRegSpace][uYRegSpace+1]; indlist[6] = m_pCurrentVertexIndicesX(uXRegSpace, uYRegSpace + 1);
} }
if (edgeTable[iCubeIndex] & 128) if (edgeTable[iCubeIndex] & 128)
{ {
indlist[7] = m_pCurrentVertexIndicesY[uXRegSpace][uYRegSpace]; indlist[7] = m_pCurrentVertexIndicesY(uXRegSpace, uYRegSpace);
} }
if (edgeTable[iCubeIndex] & 256) if (edgeTable[iCubeIndex] & 256)
{ {
indlist[8] = m_pPreviousVertexIndicesZ[uXRegSpace][uYRegSpace]; indlist[8] = m_pPreviousVertexIndicesZ(uXRegSpace, uYRegSpace);
} }
if (edgeTable[iCubeIndex] & 512) if (edgeTable[iCubeIndex] & 512)
{ {
indlist[9] = m_pPreviousVertexIndicesZ[uXRegSpace+1][uYRegSpace]; indlist[9] = m_pPreviousVertexIndicesZ(uXRegSpace + 1, uYRegSpace);
} }
if (edgeTable[iCubeIndex] & 1024) if (edgeTable[iCubeIndex] & 1024)
{ {
indlist[10] = m_pPreviousVertexIndicesZ[uXRegSpace+1][uYRegSpace+1]; indlist[10] = m_pPreviousVertexIndicesZ(uXRegSpace + 1, uYRegSpace + 1);
} }
if (edgeTable[iCubeIndex] & 2048) if (edgeTable[iCubeIndex] & 2048)
{ {
indlist[11] = m_pPreviousVertexIndicesZ[uXRegSpace][uYRegSpace+1]; indlist[11] = m_pPreviousVertexIndicesZ(uXRegSpace, uYRegSpace + 1);
} }
for (int i=0;triTable[iCubeIndex][i]!=-1;i+=3) for (int i=0;triTable[iCubeIndex][i]!=-1;i+=3)

View File

@ -33,7 +33,7 @@ namespace PolyVox
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Array // Array
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template<uint32_t dimensions, typename ElementType> class Array; /*template<uint32_t dimensions, typename ElementType> class Array;
typedef Array<1,float> Array1DFloat; typedef Array<1,float> Array1DFloat;
typedef Array<1,double> Array1DDouble; typedef Array<1,double> Array1DDouble;
@ -42,25 +42,25 @@ namespace PolyVox
typedef Array<1,int16_t> Array1DInt16; typedef Array<1,int16_t> Array1DInt16;
typedef Array<1,uint16_t> Array1DUint16; typedef Array<1,uint16_t> Array1DUint16;
typedef Array<1,int32_t> Array1DInt32; typedef Array<1,int32_t> Array1DInt32;
typedef Array<1,uint32_t> Array1DUint32; typedef Array<1,uint32_t> Array1DUint32;*/
typedef Array<2,float> Array2DFloat; /*typedef Array<2,float> Array2DFloat;
typedef Array<2,double> Array2DDouble; typedef Array<2,double> Array2DDouble;
typedef Array<2,int8_t> Array2DInt8; typedef Array<2,int8_t> Array2DInt8;
typedef Array<2,uint8_t> Array2DUint8; typedef Array<2,uint8_t> Array2DUint8;
typedef Array<2,int16_t> Array2DInt16; typedef Array<2,int16_t> Array2DInt16;
typedef Array<2,uint16_t> Array2DUint16; typedef Array<2,uint16_t> Array2DUint16;
typedef Array<2,int32_t> Array2DInt32; typedef Array<2,int32_t> Array2DInt32;
typedef Array<2,uint32_t> Array2DUint32; typedef Array<2,uint32_t> Array2DUint32;*/
typedef Array<3,float> Array3DFloat; /*typedef Array<3,float> Array3DFloat;
typedef Array<3,double> Array3DDouble; typedef Array<3,double> Array3DDouble;
typedef Array<3,int8_t> Array3DInt8; typedef Array<3,int8_t> Array3DInt8;
typedef Array<3,uint8_t> Array3DUint8; typedef Array<3,uint8_t> Array3DUint8;
typedef Array<3,int16_t> Array3DInt16; typedef Array<3,int16_t> Array3DInt16;
typedef Array<3,uint16_t> Array3DUint16; typedef Array<3,uint16_t> Array3DUint16;
typedef Array<3,int32_t> Array3DInt32; typedef Array<3,int32_t> Array3DInt32;
typedef Array<3,uint32_t> Array3DUint32; typedef Array<3,uint32_t> Array3DUint32;*/
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// BlockCompressor // BlockCompressor

View File

@ -374,10 +374,10 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) const VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) const
{ {
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner(); const Region& regValidRegion = this->m_regValidRegion;
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX(); int32_t iLocalXPos = uXPos - regValidRegion.getLowerX();
int32_t iLocalYPos = uYPos - v3dLowerCorner.getY(); int32_t iLocalYPos = uYPos - regValidRegion.getLowerY();
int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ(); int32_t iLocalZPos = uZPos - regValidRegion.getLowerZ();
return m_pData return m_pData
[ [

View File

@ -1,57 +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.
*******************************************************************************/
#include "PolyVoxCore/ArraySizes.h"
#include <cstdint>
namespace PolyVox
{
/**
\param uSize The size of the first dimension.
*/
ArraySizes::ArraySizes(uint32_t uSize)
{
m_pSizes[0]=uSize;
}
/**
This class only directly implements one dimensional sizes. Higher numbers
of dimensions are implemented via the ArraySisesImpl class. This function
create an object of the next dimensionality up.
\param uSize The size of the next dimension.
\return A higher dimension version of this class.
*/
ArraySizesImpl<2> ArraySizes::operator () (uint32_t uSize)
{
return ArraySizesImpl<2>(m_pSizes, uSize);
}
/**
\return The array of integers corresponding to this object.
*/
ArraySizes::operator UIntArray1 () const
{
return m_pSizes;
}
}

View File

@ -68,7 +68,7 @@ void TestAmbientOcclusionGenerator::testExecute()
//Create an array to store the result. Array can be smaller than the volume by an integer amount. //Create an array to store the result. Array can be smaller than the volume by an integer amount.
const int32_t g_uArraySideLength = g_uVolumeSideLength / 2; const int32_t g_uArraySideLength = g_uVolumeSideLength / 2;
Array<3, uint8_t> ambientOcclusionResult(ArraySizes(g_uArraySideLength)(g_uArraySideLength)(g_uArraySideLength)); Array<3, uint8_t> ambientOcclusionResult(g_uArraySideLength, g_uArraySideLength, g_uArraySideLength);
// Calculate the ambient occlusion values // Calculate the ambient occlusion values
IsVoxelTransparent isVoxelTransparent; IsVoxelTransparent isVoxelTransparent;
@ -78,11 +78,11 @@ void TestAmbientOcclusionGenerator::testExecute()
//Check the results by sampling along a line though the centre of the volume. Because //Check the results by sampling along a line though the centre of the volume. Because
//of the two walls we added, samples in the middle are darker than those at the edge. //of the two walls we added, samples in the middle are darker than those at the edge.
QCOMPARE(static_cast<int>(ambientOcclusionResult[16][ 0][16]), 178); QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 0, 16)), 178);
QCOMPARE(static_cast<int>(ambientOcclusionResult[16][ 8][16]), 109); QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 8, 16)), 109);
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 //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, volData.getEnclosingRegion(), 32.0f, 8, &isVoxelTransparentFunction);

View File

@ -29,13 +29,67 @@ freely, subject to the following restrictions:
using namespace PolyVox; using namespace PolyVox;
void TestArray::testCArraySpeed()
{
const int width = 64;
const int height = 32;
const int depth = 16;
int cArray[width][height][depth];
QBENCHMARK
{
int ct = 1;
int expectedTotal = 0;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
cArray[x][y][z] = ct;
expectedTotal += cArray[x][y][z];
ct++;
}
}
}
}
}
void TestArray::testPolyVoxArraySpeed()
{
const int width = 64;
const int height = 32;
const int depth = 16;
Array<3, int> polyvoxArray(width, height, depth);
QBENCHMARK
{
int ct = 1;
int expectedTotal = 0;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
polyvoxArray(x, y, z) = ct;
expectedTotal += polyvoxArray(x, y, z);
ct++;
}
}
}
}
}
void TestArray::testReadWrite() void TestArray::testReadWrite()
{ {
int width = 5; int width = 5;
int height = 10; int height = 10;
int depth = 20; int depth = 20;
Array<3, int> myArray(ArraySizes(width)(height)(depth)); Array<3, int> myArray(width, height, depth);
int ct = 1; int ct = 1;
int expectedTotal = 0; int expectedTotal = 0;
@ -45,8 +99,8 @@ void TestArray::testReadWrite()
{ {
for(int x = 0; x < width; x++) for(int x = 0; x < width; x++)
{ {
myArray[x][y][z] = ct; myArray(x, y, z) = ct;
expectedTotal += myArray[x][y][z]; expectedTotal += myArray(x, y, z);
ct++; ct++;
} }
} }
@ -60,8 +114,8 @@ void TestArray::testReadWrite()
{ {
for(int x = 0; x < width; x++) for(int x = 0; x < width; x++)
{ {
QCOMPARE(myArray[x][y][z], ct); QCOMPARE(myArray(x, y, z), ct);
total += myArray[x][y][z]; total += myArray(x, y, z);
ct++; ct++;
} }
} }

View File

@ -31,6 +31,8 @@ class TestArray: public QObject
Q_OBJECT Q_OBJECT
private slots: private slots:
void testCArraySpeed();
void testPolyVoxArraySpeed();
void testReadWrite(); void testReadWrite();
}; };

View File

@ -24,6 +24,7 @@ freely, subject to the following restrictions:
#include "TestVolumeSubclass.h" #include "TestVolumeSubclass.h"
#include "PolyVoxCore/Array.h" #include "PolyVoxCore/Array.h"
#include "PolyVoxCore/BaseVolume.h" #include "PolyVoxCore/BaseVolume.h"
#include "PolyVoxCore/CubicSurfaceExtractor.h" #include "PolyVoxCore/CubicSurfaceExtractor.h"
#include "PolyVoxCore/Material.h" #include "PolyVoxCore/Material.h"
@ -62,8 +63,9 @@ public:
/// Constructor for creating a fixed size volume. /// Constructor for creating a fixed size volume.
VolumeSubclass(const Region& regValid) VolumeSubclass(const Region& regValid)
:BaseVolume<VoxelType>(regValid) :BaseVolume<VoxelType>(regValid)
, mVolumeData(this->getWidth(), this->getHeight(), this->getDepth())
{ {
mVolumeData.resize(ArraySizes(this->getWidth())(this->getHeight())(this->getDepth())); //mVolumeData.resize(ArraySizes(this->getWidth())(this->getHeight())(this->getDepth()));
} }
/// Destructor /// Destructor
~VolumeSubclass() {}; ~VolumeSubclass() {};
@ -97,7 +99,7 @@ public:
POLYVOX_THROW(std::out_of_range, "Position is outside valid region"); POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
} }
return mVolumeData[uXPos][uYPos][uZPos]; return mVolumeData(uXPos, uYPos, uZPos);
} }
case WrapModes::Clamp: case WrapModes::Clamp:
{ {
@ -108,13 +110,13 @@ public:
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX()); uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY()); uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ()); uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
return mVolumeData[uXPos][uYPos][uZPos]; return mVolumeData(uXPos, uYPos, uZPos);
} }
case WrapModes::Border: case WrapModes::Border:
{ {
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos)) if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
{ {
return mVolumeData[uXPos][uYPos][uZPos]; return mVolumeData(uXPos, uYPos, uZPos);
} }
else else
{ {
@ -123,7 +125,7 @@ public:
} }
case WrapModes::AssumeValid: case WrapModes::AssumeValid:
{ {
return mVolumeData[uXPos][uYPos][uZPos]; return mVolumeData(uXPos, uYPos, uZPos);
} }
default: default:
{ {
@ -147,7 +149,7 @@ public:
{ {
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos))) if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)))
{ {
mVolumeData[uXPos][uYPos][uZPos] = tValue; mVolumeData(uXPos, uYPos, uZPos) = tValue;
return true; return true;
} }
else else