From 458a534bf31f108993dd75029d128aed7b5bd96a Mon Sep 17 00:00:00 2001 From: David Williams Date: Wed, 20 Aug 2014 17:18:20 +0200 Subject: [PATCH 01/16] Eliminated creation of temporary vector. --- library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl index c76601b8..3505528b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl @@ -374,10 +374,10 @@ namespace PolyVox template VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType, VoxelType /*tBorder*/) const { - const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner(); - int32_t iLocalXPos = uXPos - v3dLowerCorner.getX(); - int32_t iLocalYPos = uYPos - v3dLowerCorner.getY(); - int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ(); + const Region& regValidRegion = this->m_regValidRegion; + int32_t iLocalXPos = uXPos - regValidRegion.getLowerX(); + int32_t iLocalYPos = uYPos - regValidRegion.getLowerY(); + int32_t iLocalZPos = uZPos - regValidRegion.getLowerZ(); return m_pData [ From d0aa7cd60f81bee3abf44f44571900464d7ac96f Mon Sep 17 00:00:00 2001 From: David Williams Date: Thu, 21 Aug 2014 00:06:20 +0200 Subject: [PATCH 02/16] Replaced usage of our 'Array' class with native C array and got significant performance increase. --- .../MarchingCubesSurfaceExtractor.h | 10 ++++---- .../MarchingCubesSurfaceExtractor.inl | 24 ++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h index cf42800e..17e30b1e 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h @@ -156,6 +156,8 @@ namespace PolyVox template< typename VolumeType, typename MeshType, typename ControllerType> class MarchingCubesSurfaceExtractor { + private: + const static int BitmaskSize = 128; public: MarchingCubesSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, ControllerType controller, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType()); @@ -164,14 +166,14 @@ namespace PolyVox private: //Compute the cell bitmask for a particular slice in z. template - uint32_t computeBitmaskForSlice(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask); + uint32_t computeBitmaskForSlice(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize]); //Compute the cell bitmask for a given cell. template - void computeBitmaskForCell(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask, uint32_t uXRegSpace, uint32_t uYRegSpace); + void computeBitmaskForCell(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize], uint32_t uXRegSpace, uint32_t uYRegSpace); //Use the cell bitmasks to generate all the vertices needed for that slice - void generateVerticesForSlice(const Array2DUint8& pCurrentBitmask, + void generateVerticesForSlice(uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize], Array2DInt32& m_pCurrentVertexIndicesX, Array2DInt32& m_pCurrentVertexIndicesY, Array2DInt32& m_pCurrentVertexIndicesZ); @@ -291,7 +293,7 @@ namespace PolyVox //////////////////////////////////////////////////////////////////////////////// //Use the cell bitmasks to generate all the indices needed for that slice - void generateIndicesForSlice(const Array2DUint8& pPreviousBitmask, + void generateIndicesForSlice(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], const Array2DInt32& m_pPreviousVertexIndicesX, const Array2DInt32& m_pPreviousVertexIndicesY, const Array2DInt32& m_pPreviousVertexIndicesZ, diff --git a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl index fd226560..39ebdeda 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl @@ -52,6 +52,12 @@ namespace PolyVox const uint32_t uArrayHeight = m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 1; const uint32_t arraySizes[2]= {uArrayWidth, uArrayHeight}; // Array dimensions + // PolyVox has a hardcoded limit on how big the regions it can extract are. This lets us allocate various + // arrays at compile time rather than run time. If you *really* need to you can increase this by changing + // the 'BitmaskSize' constant, but you should be sure you really know what you are doing. + POLYVOX_THROW_IF(uArrayWidth > BitmaskSize, std::invalid_argument, "Requested extraction region is too large"); + POLYVOX_THROW_IF(uArrayHeight > BitmaskSize, std::invalid_argument, "Requested extraction region is too large"); + //For edge indices Array2DInt32 m_pPreviousVertexIndicesX(arraySizes); Array2DInt32 m_pPreviousVertexIndicesY(arraySizes); @@ -60,8 +66,8 @@ namespace PolyVox Array2DInt32 m_pCurrentVertexIndicesY(arraySizes); Array2DInt32 m_pCurrentVertexIndicesZ(arraySizes); - Array2DUint8 pPreviousBitmask(arraySizes); - Array2DUint8 pCurrentBitmask(arraySizes); + uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize]; + uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize]; //Create a region corresponding to the first slice m_regSlicePrevious = m_regSizeInVoxels; @@ -86,7 +92,8 @@ namespace PolyVox } std::swap(uNoOfNonEmptyCellsForSlice0, uNoOfNonEmptyCellsForSlice1); - pPreviousBitmask.swap(pCurrentBitmask); + //pPreviousBitmask.swap(pCurrentBitmask); + memcpy(pPreviousBitmask, pCurrentBitmask, BitmaskSize * BitmaskSize); m_pPreviousVertexIndicesX.swap(m_pCurrentVertexIndicesX); m_pPreviousVertexIndicesY.swap(m_pCurrentVertexIndicesY); m_pPreviousVertexIndicesZ.swap(m_pCurrentVertexIndicesZ); @@ -114,7 +121,8 @@ namespace PolyVox } std::swap(uNoOfNonEmptyCellsForSlice0, uNoOfNonEmptyCellsForSlice1); - pPreviousBitmask.swap(pCurrentBitmask); + //pPreviousBitmask.swap(pCurrentBitmask); + memcpy(pPreviousBitmask, pCurrentBitmask, BitmaskSize * BitmaskSize); m_pPreviousVertexIndicesX.swap(m_pCurrentVertexIndicesX); m_pPreviousVertexIndicesY.swap(m_pCurrentVertexIndicesY); m_pPreviousVertexIndicesZ.swap(m_pCurrentVertexIndicesZ); @@ -132,7 +140,7 @@ namespace PolyVox template template - uint32_t MarchingCubesSurfaceExtractor::computeBitmaskForSlice(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask) + uint32_t MarchingCubesSurfaceExtractor::computeBitmaskForSlice(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize]) { m_uNoOfOccupiedCells = 0; @@ -198,7 +206,7 @@ namespace PolyVox template template - void MarchingCubesSurfaceExtractor::computeBitmaskForCell(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask, uint32_t uXRegSpace, uint32_t uYRegSpace) + void MarchingCubesSurfaceExtractor::computeBitmaskForCell(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize], uint32_t uXRegSpace, uint32_t uYRegSpace) { uint8_t iCubeIndex = 0; @@ -397,7 +405,7 @@ namespace PolyVox } template - void MarchingCubesSurfaceExtractor::generateVerticesForSlice(const Array2DUint8& pCurrentBitmask, + void MarchingCubesSurfaceExtractor::generateVerticesForSlice(uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize], Array2DInt32& m_pCurrentVertexIndicesX, Array2DInt32& m_pCurrentVertexIndicesY, Array2DInt32& m_pCurrentVertexIndicesZ) @@ -537,7 +545,7 @@ namespace PolyVox } template - void MarchingCubesSurfaceExtractor::generateIndicesForSlice(const Array2DUint8& pPreviousBitmask, + void MarchingCubesSurfaceExtractor::generateIndicesForSlice(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], const Array2DInt32& m_pPreviousVertexIndicesX, const Array2DInt32& m_pPreviousVertexIndicesY, const Array2DInt32& m_pPreviousVertexIndicesZ, From d9f328cadb5d605e2c19a9a9894514863da12c23 Mon Sep 17 00:00:00 2001 From: David Williams Date: Thu, 21 Aug 2014 16:57:23 +0200 Subject: [PATCH 03/16] It seems the PolyVox Array class is really slow compared to raw C arrays. I've added a test ready for some experimentation. --- tests/TestArray.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++ tests/TestArray.h | 2 ++ 2 files changed, 48 insertions(+) diff --git a/tests/TestArray.cpp b/tests/TestArray.cpp index bc3f8644..8dde377a 100644 --- a/tests/TestArray.cpp +++ b/tests/TestArray.cpp @@ -29,6 +29,52 @@ freely, subject to the following restrictions: using namespace PolyVox; +void TestArray::testCArraySpeed() +{ + const int width = 128; + const int height = 128; + + int cArray[width][height]; + + QBENCHMARK + { + int ct = 1; + int expectedTotal = 0; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + cArray[x][y] = ct; + expectedTotal += cArray[x][y]; + ct++; + } + } + } +} + +void TestArray::testPolyVoxArraySpeed() +{ + const int width = 128; + const int height = 128; + + Array<2, int> polyvoxArray(ArraySizes(width)(height)); + + QBENCHMARK + { + int ct = 1; + int expectedTotal = 0; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + polyvoxArray[x][y] = ct; + expectedTotal += polyvoxArray[x][y]; + ct++; + } + } + } +} + void TestArray::testReadWrite() { int width = 5; diff --git a/tests/TestArray.h b/tests/TestArray.h index fe935511..2d3e5951 100644 --- a/tests/TestArray.h +++ b/tests/TestArray.h @@ -31,6 +31,8 @@ class TestArray: public QObject Q_OBJECT private slots: + void testCArraySpeed(); + void testPolyVoxArraySpeed(); void testReadWrite(); }; From 46358adfbc7061dd500f6d5e42197c89b709c6a1 Mon Sep 17 00:00:00 2001 From: David Williams Date: Thu, 21 Aug 2014 21:31:09 +0200 Subject: [PATCH 04/16] New array class is 50(!) times faster than the old one on raw read-write performance. It's also significantly simply. --- tests/TestArray.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++ tests/TestArray.h | 1 + 2 files changed, 54 insertions(+) diff --git a/tests/TestArray.cpp b/tests/TestArray.cpp index 8dde377a..bf024061 100644 --- a/tests/TestArray.cpp +++ b/tests/TestArray.cpp @@ -29,6 +29,36 @@ freely, subject to the following restrictions: using namespace PolyVox; +template +class Array2D +{ +public: + + Array2D(uint32_t width, uint32_t height) + :m_uWidth(width) + ,m_uHeight(height) + ,m_pData(0) + { + m_pData = new ElementType[m_uWidth * m_uHeight]; + } + + ~Array2D() + { + delete[] m_pData; + } + + ElementType& operator()(uint32_t x, uint32_t y) + { + return m_pData[y * m_uWidth + x]; + } + +private: + + uint32_t m_uWidth; + uint32_t m_uHeight; + ElementType* m_pData; +}; + void TestArray::testCArraySpeed() { const int width = 128; @@ -75,6 +105,29 @@ void TestArray::testPolyVoxArraySpeed() } } +void TestArray::testPolyVoxArray2DSpeed() +{ + const int width = 128; + const int height = 128; + + Array2D polyvoxArray(width,height); + + QBENCHMARK + { + int ct = 1; + int expectedTotal = 0; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + polyvoxArray(x,y) = ct; + expectedTotal += polyvoxArray(x,y); + ct++; + } + } + } +} + void TestArray::testReadWrite() { int width = 5; diff --git a/tests/TestArray.h b/tests/TestArray.h index 2d3e5951..bd5425a6 100644 --- a/tests/TestArray.h +++ b/tests/TestArray.h @@ -33,6 +33,7 @@ class TestArray: public QObject private slots: void testCArraySpeed(); void testPolyVoxArraySpeed(); + void testPolyVoxArray2DSpeed(); void testReadWrite(); }; From 20815b608383f1a622b7a1b424420e4626f9665c Mon Sep 17 00:00:00 2001 From: David Williams Date: Thu, 21 Aug 2014 21:38:19 +0200 Subject: [PATCH 05/16] Moved Array2D to it's own file. --- library/PolyVoxCore/CMakeLists.txt | 1 + .../include/PolyVoxCore/Impl/Array2D.h | 60 +++++++++++++++++++ tests/TestArray.cpp | 32 +--------- 3 files changed, 63 insertions(+), 30 deletions(-) create mode 100644 library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h diff --git a/library/PolyVoxCore/CMakeLists.txt b/library/PolyVoxCore/CMakeLists.txt index db5caaa8..ed06c3c6 100644 --- a/library/PolyVoxCore/CMakeLists.txt +++ b/library/PolyVoxCore/CMakeLists.txt @@ -108,6 +108,7 @@ SET(IMPL_SRC_FILES ) SET(IMPL_INC_FILES + include/PolyVoxCore/Impl/Array2D.h include/PolyVoxCore/Impl/ArraySizesImpl.h include/PolyVoxCore/Impl/ArraySizesImpl.inl include/PolyVoxCore/Impl/AStarPathfinderImpl.h diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h new file mode 100644 index 00000000..635a6328 --- /dev/null +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h @@ -0,0 +1,60 @@ +/******************************************************************************* +Copyright (c) 2005-20014 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_Array2D_H__ +#define __PolyVox_Array2D_H__ + +namespace PolyVox +{ + template + class Array2D + { + public: + + Array2D(uint32_t width, uint32_t height) + :m_uWidth(width) + , m_uHeight(height) + , m_pData(0) + { + m_pData = new ElementType[m_uWidth * m_uHeight]; + } + + ~Array2D() + { + delete[] m_pData; + } + + ElementType& operator()(uint32_t x, uint32_t y) + { + return m_pData[y * m_uWidth + x]; + } + + private: + + uint32_t m_uWidth; + uint32_t m_uHeight; + ElementType* m_pData; + }; +} + +#endif //__PolyVox_Array2D_H__ \ No newline at end of file diff --git a/tests/TestArray.cpp b/tests/TestArray.cpp index bf024061..6d41aa6e 100644 --- a/tests/TestArray.cpp +++ b/tests/TestArray.cpp @@ -25,40 +25,12 @@ freely, subject to the following restrictions: #include "PolyVoxCore/Array.h" +#include "PolyVoxCore/Impl/Array2D.h" + #include using namespace PolyVox; -template -class Array2D -{ -public: - - Array2D(uint32_t width, uint32_t height) - :m_uWidth(width) - ,m_uHeight(height) - ,m_pData(0) - { - m_pData = new ElementType[m_uWidth * m_uHeight]; - } - - ~Array2D() - { - delete[] m_pData; - } - - ElementType& operator()(uint32_t x, uint32_t y) - { - return m_pData[y * m_uWidth + x]; - } - -private: - - uint32_t m_uWidth; - uint32_t m_uHeight; - ElementType* m_pData; -}; - void TestArray::testCArraySpeed() { const int width = 128; From 5f8e3df5dfa239b86fc8cc55ab93028ee0a853ea Mon Sep 17 00:00:00 2001 From: David Williams Date: Thu, 21 Aug 2014 21:38:36 +0200 Subject: [PATCH 06/16] Revert "Replaced usage of our 'Array' class with native C array and got significant performance increase." This reverts commit d0aa7cd60f81bee3abf44f44571900464d7ac96f. --- .../MarchingCubesSurfaceExtractor.h | 10 ++++---- .../MarchingCubesSurfaceExtractor.inl | 24 +++++++------------ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h index 17e30b1e..cf42800e 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h @@ -156,8 +156,6 @@ namespace PolyVox template< typename VolumeType, typename MeshType, typename ControllerType> class MarchingCubesSurfaceExtractor { - private: - const static int BitmaskSize = 128; public: MarchingCubesSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, ControllerType controller, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType()); @@ -166,14 +164,14 @@ namespace PolyVox private: //Compute the cell bitmask for a particular slice in z. template - uint32_t computeBitmaskForSlice(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize]); + uint32_t computeBitmaskForSlice(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask); //Compute the cell bitmask for a given cell. template - void computeBitmaskForCell(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize], uint32_t uXRegSpace, uint32_t uYRegSpace); + void computeBitmaskForCell(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask, uint32_t uXRegSpace, uint32_t uYRegSpace); //Use the cell bitmasks to generate all the vertices needed for that slice - void generateVerticesForSlice(uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize], + void generateVerticesForSlice(const Array2DUint8& pCurrentBitmask, Array2DInt32& m_pCurrentVertexIndicesX, Array2DInt32& m_pCurrentVertexIndicesY, Array2DInt32& m_pCurrentVertexIndicesZ); @@ -293,7 +291,7 @@ namespace PolyVox //////////////////////////////////////////////////////////////////////////////// //Use the cell bitmasks to generate all the indices needed for that slice - void generateIndicesForSlice(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], + void generateIndicesForSlice(const Array2DUint8& pPreviousBitmask, const Array2DInt32& m_pPreviousVertexIndicesX, const Array2DInt32& m_pPreviousVertexIndicesY, const Array2DInt32& m_pPreviousVertexIndicesZ, diff --git a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl index 39ebdeda..fd226560 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl @@ -52,12 +52,6 @@ namespace PolyVox const uint32_t uArrayHeight = m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 1; const uint32_t arraySizes[2]= {uArrayWidth, uArrayHeight}; // Array dimensions - // PolyVox has a hardcoded limit on how big the regions it can extract are. This lets us allocate various - // arrays at compile time rather than run time. If you *really* need to you can increase this by changing - // the 'BitmaskSize' constant, but you should be sure you really know what you are doing. - POLYVOX_THROW_IF(uArrayWidth > BitmaskSize, std::invalid_argument, "Requested extraction region is too large"); - POLYVOX_THROW_IF(uArrayHeight > BitmaskSize, std::invalid_argument, "Requested extraction region is too large"); - //For edge indices Array2DInt32 m_pPreviousVertexIndicesX(arraySizes); Array2DInt32 m_pPreviousVertexIndicesY(arraySizes); @@ -66,8 +60,8 @@ namespace PolyVox Array2DInt32 m_pCurrentVertexIndicesY(arraySizes); Array2DInt32 m_pCurrentVertexIndicesZ(arraySizes); - uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize]; - uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize]; + Array2DUint8 pPreviousBitmask(arraySizes); + Array2DUint8 pCurrentBitmask(arraySizes); //Create a region corresponding to the first slice m_regSlicePrevious = m_regSizeInVoxels; @@ -92,8 +86,7 @@ namespace PolyVox } std::swap(uNoOfNonEmptyCellsForSlice0, uNoOfNonEmptyCellsForSlice1); - //pPreviousBitmask.swap(pCurrentBitmask); - memcpy(pPreviousBitmask, pCurrentBitmask, BitmaskSize * BitmaskSize); + pPreviousBitmask.swap(pCurrentBitmask); m_pPreviousVertexIndicesX.swap(m_pCurrentVertexIndicesX); m_pPreviousVertexIndicesY.swap(m_pCurrentVertexIndicesY); m_pPreviousVertexIndicesZ.swap(m_pCurrentVertexIndicesZ); @@ -121,8 +114,7 @@ namespace PolyVox } std::swap(uNoOfNonEmptyCellsForSlice0, uNoOfNonEmptyCellsForSlice1); - //pPreviousBitmask.swap(pCurrentBitmask); - memcpy(pPreviousBitmask, pCurrentBitmask, BitmaskSize * BitmaskSize); + pPreviousBitmask.swap(pCurrentBitmask); m_pPreviousVertexIndicesX.swap(m_pCurrentVertexIndicesX); m_pPreviousVertexIndicesY.swap(m_pCurrentVertexIndicesY); m_pPreviousVertexIndicesZ.swap(m_pCurrentVertexIndicesZ); @@ -140,7 +132,7 @@ namespace PolyVox template template - uint32_t MarchingCubesSurfaceExtractor::computeBitmaskForSlice(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize]) + uint32_t MarchingCubesSurfaceExtractor::computeBitmaskForSlice(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask) { m_uNoOfOccupiedCells = 0; @@ -206,7 +198,7 @@ namespace PolyVox template template - void MarchingCubesSurfaceExtractor::computeBitmaskForCell(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize], uint32_t uXRegSpace, uint32_t uYRegSpace) + void MarchingCubesSurfaceExtractor::computeBitmaskForCell(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask, uint32_t uXRegSpace, uint32_t uYRegSpace) { uint8_t iCubeIndex = 0; @@ -405,7 +397,7 @@ namespace PolyVox } template - void MarchingCubesSurfaceExtractor::generateVerticesForSlice(uint8_t pCurrentBitmask[BitmaskSize][BitmaskSize], + void MarchingCubesSurfaceExtractor::generateVerticesForSlice(const Array2DUint8& pCurrentBitmask, Array2DInt32& m_pCurrentVertexIndicesX, Array2DInt32& m_pCurrentVertexIndicesY, Array2DInt32& m_pCurrentVertexIndicesZ) @@ -545,7 +537,7 @@ namespace PolyVox } template - void MarchingCubesSurfaceExtractor::generateIndicesForSlice(uint8_t pPreviousBitmask[BitmaskSize][BitmaskSize], + void MarchingCubesSurfaceExtractor::generateIndicesForSlice(const Array2DUint8& pPreviousBitmask, const Array2DInt32& m_pPreviousVertexIndicesX, const Array2DInt32& m_pPreviousVertexIndicesY, const Array2DInt32& m_pPreviousVertexIndicesZ, From 83c287727fa8177ee9c3ff6cee357c054783739d Mon Sep 17 00:00:00 2001 From: David Williams Date: Thu, 21 Aug 2014 23:03:38 +0200 Subject: [PATCH 07/16] Additions to Array2D. --- .../PolyVoxCore/include/PolyVoxCore/Array.h | 4 +- .../include/PolyVoxCore/Impl/Array2D.h | 39 +++++++++++++++++++ .../PolyVoxCore/PolyVoxForwardDeclarations.h | 4 +- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/Array.h b/library/PolyVoxCore/include/PolyVoxCore/Array.h index e8a51b05..ae59524a 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Array.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Array.h @@ -171,7 +171,7 @@ namespace PolyVox typedef Array<1,uint32_t> Array1DUint32; ///A 2D Array of floats. - typedef Array<2,float> Array2DFloat; + /*typedef Array<2,float> Array2DFloat; ///A 2D Array of doubles. typedef Array<2,double> Array2DDouble; ///A 2D Array of signed 8-bit values. @@ -185,7 +185,7 @@ namespace PolyVox ///A 2D Array of signed 32-bit values. typedef Array<2,int32_t> Array2DInt32; ///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. typedef Array<3,float> Array3DFloat; diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h index 635a6328..b6713ae9 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h @@ -44,17 +44,56 @@ namespace PolyVox delete[] m_pData; } + ElementType operator()(uint32_t x, uint32_t y) const + { + return m_pData[y * m_uWidth + x]; + } + ElementType& operator()(uint32_t x, uint32_t y) { return m_pData[y * m_uWidth + x]; } + ElementType* getRawData() + { + return m_pData; + } + + size_t getNoOfElements() + { + return m_uWidth * m_uHeight; + } + + void swap(Array2D& other) + { + ElementType* temp = other.m_pData; + other.m_pData = m_pData; + m_pData = temp; + } + private: uint32_t m_uWidth; uint32_t m_uHeight; ElementType* m_pData; }; + + ///A 2D Array of floats. + typedef Array2D Array2DFloat; + ///A 2D Array of doubles. + typedef Array2D Array2DDouble; + ///A 2D Array of signed 8-bit values. + typedef Array2D Array2DInt8; + ///A 2D Array of unsigned 8-bit values. + typedef Array2D Array2DUint8; + ///A 2D Array of signed 16-bit values. + typedef Array2D Array2DInt16; + ///A 2D Array of unsigned 16-bit values. + typedef Array2D Array2DUint16; + ///A 2D Array of signed 32-bit values. + typedef Array2D Array2DInt32; + ///A 2D Array of unsigned 32-bit values. + typedef Array2D Array2DUint32; } #endif //__PolyVox_Array2D_H__ \ No newline at end of file diff --git a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h index 0b401a98..75ddf905 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h +++ b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h @@ -44,14 +44,14 @@ namespace PolyVox typedef Array<1,int32_t> Array1DInt32; typedef Array<1,uint32_t> Array1DUint32; - typedef Array<2,float> Array2DFloat; + /*typedef Array<2,float> Array2DFloat; typedef Array<2,double> Array2DDouble; typedef Array<2,int8_t> Array2DInt8; typedef Array<2,uint8_t> Array2DUint8; typedef Array<2,int16_t> Array2DInt16; typedef Array<2,uint16_t> Array2DUint16; 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,double> Array3DDouble; From 0ff0234ce19c462287d86a6b4a258e3c6a54f571 Mon Sep 17 00:00:00 2001 From: David Williams Date: Thu, 21 Aug 2014 23:04:30 +0200 Subject: [PATCH 08/16] Switched marching cubes extractor to use new Array2D instead of array, and it now more than twice as fast in the best case (empty volume). --- .../MarchingCubesSurfaceExtractor.h | 2 +- .../MarchingCubesSurfaceExtractor.inl | 76 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h index cf42800e..62ccbff6 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h @@ -27,7 +27,7 @@ freely, subject to the following restrictions: #include "Impl/MarchingCubesTables.h" #include "Impl/TypeDef.h" -#include "PolyVoxCore/Array.h" +#include "PolyVoxCore/Impl/Array2D.h" #include "PolyVoxCore/BaseVolume.h" //For wrap modes... should move these? #include "PolyVoxCore/Mesh.h" #include "PolyVoxCore/DefaultMarchingCubesController.h" diff --git a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl index fd226560..acd0f77b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl @@ -53,15 +53,15 @@ namespace PolyVox const uint32_t arraySizes[2]= {uArrayWidth, uArrayHeight}; // Array dimensions //For edge indices - Array2DInt32 m_pPreviousVertexIndicesX(arraySizes); - Array2DInt32 m_pPreviousVertexIndicesY(arraySizes); - Array2DInt32 m_pPreviousVertexIndicesZ(arraySizes); - Array2DInt32 m_pCurrentVertexIndicesX(arraySizes); - Array2DInt32 m_pCurrentVertexIndicesY(arraySizes); - Array2DInt32 m_pCurrentVertexIndicesZ(arraySizes); + Array2DInt32 m_pPreviousVertexIndicesX(uArrayWidth, uArrayHeight); + Array2DInt32 m_pPreviousVertexIndicesY(uArrayWidth, uArrayHeight); + Array2DInt32 m_pPreviousVertexIndicesZ(uArrayWidth, uArrayHeight); + Array2DInt32 m_pCurrentVertexIndicesX(uArrayWidth, uArrayHeight); + Array2DInt32 m_pCurrentVertexIndicesY(uArrayWidth, uArrayHeight); + Array2DInt32 m_pCurrentVertexIndicesZ(uArrayWidth, uArrayHeight); - Array2DUint8 pPreviousBitmask(arraySizes); - Array2DUint8 pCurrentBitmask(arraySizes); + Array2DUint8 pPreviousBitmask(uArrayWidth, uArrayHeight); + Array2DUint8 pCurrentBitmask(uArrayWidth, uArrayHeight); //Create a region corresponding to the first slice m_regSlicePrevious = m_regSizeInVoxels; @@ -220,16 +220,16 @@ namespace PolyVox v111 = m_sampVolume.peekVoxel1px1py1pz(); //z - uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; + uint8_t iPreviousCubeIndexZ = pPreviousBitmask(uXRegSpace, uYRegSpace); iPreviousCubeIndexZ >>= 4; //y - uint8_t iPreviousCubeIndexY = pCurrentBitmask[uXRegSpace][uYRegSpace-1]; + uint8_t iPreviousCubeIndexY = pCurrentBitmask(uXRegSpace, uYRegSpace - 1); iPreviousCubeIndexY &= 192; //192 = 128 + 64 iPreviousCubeIndexY >>= 2; //x - uint8_t iPreviousCubeIndexX = pCurrentBitmask[uXRegSpace-1][uYRegSpace]; + uint8_t iPreviousCubeIndexX = pCurrentBitmask(uXRegSpace - 1, uYRegSpace); iPreviousCubeIndexX &= 128; iPreviousCubeIndexX >>= 1; @@ -243,11 +243,11 @@ namespace PolyVox v111 = m_sampVolume.peekVoxel1px1py1pz(); //z - uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; + uint8_t iPreviousCubeIndexZ = pPreviousBitmask(uXRegSpace, uYRegSpace); iPreviousCubeIndexZ >>= 4; //y - uint8_t iPreviousCubeIndexY = pCurrentBitmask[uXRegSpace][uYRegSpace-1]; + uint8_t iPreviousCubeIndexY = pCurrentBitmask(uXRegSpace, uYRegSpace - 1); iPreviousCubeIndexY &= 192; //192 = 128 + 64 iPreviousCubeIndexY >>= 2; @@ -265,11 +265,11 @@ namespace PolyVox v111 = m_sampVolume.peekVoxel1px1py1pz(); //z - uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; + uint8_t iPreviousCubeIndexZ = pPreviousBitmask(uXRegSpace, uYRegSpace); iPreviousCubeIndexZ >>= 4; //x - uint8_t iPreviousCubeIndexX = pCurrentBitmask[uXRegSpace-1][uYRegSpace]; + uint8_t iPreviousCubeIndexX = pCurrentBitmask(uXRegSpace - 1, uYRegSpace); iPreviousCubeIndexX &= 160; //160 = 128+32 iPreviousCubeIndexX >>= 1; @@ -286,7 +286,7 @@ namespace PolyVox v111 = m_sampVolume.peekVoxel1px1py1pz(); //z - uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; + uint8_t iPreviousCubeIndexZ = pPreviousBitmask(uXRegSpace, uYRegSpace); iCubeIndex = iPreviousCubeIndexZ >> 4; if (m_controller.convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; @@ -306,12 +306,12 @@ namespace PolyVox v111 = m_sampVolume.peekVoxel1px1py1pz(); //y - uint8_t iPreviousCubeIndexY = pCurrentBitmask[uXRegSpace][uYRegSpace-1]; + uint8_t iPreviousCubeIndexY = pCurrentBitmask(uXRegSpace, uYRegSpace - 1); iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 iPreviousCubeIndexY >>= 2; //x - uint8_t iPreviousCubeIndexX = pCurrentBitmask[uXRegSpace-1][uYRegSpace]; + uint8_t iPreviousCubeIndexX = pCurrentBitmask(uXRegSpace - 1, uYRegSpace); iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 iPreviousCubeIndexX >>= 1; @@ -329,7 +329,7 @@ namespace PolyVox v111 = m_sampVolume.peekVoxel1px1py1pz(); //y - uint8_t iPreviousCubeIndexY = pCurrentBitmask[uXRegSpace][uYRegSpace-1]; + uint8_t iPreviousCubeIndexY = pCurrentBitmask(uXRegSpace, uYRegSpace - 1); iPreviousCubeIndexY &= 204; //204 = 128+64+8+4 iPreviousCubeIndexY >>= 2; @@ -352,7 +352,7 @@ namespace PolyVox v111 = m_sampVolume.peekVoxel1px1py1pz(); //x - uint8_t iPreviousCubeIndexX = pCurrentBitmask[uXRegSpace-1][uYRegSpace]; + uint8_t iPreviousCubeIndexX = pCurrentBitmask(uXRegSpace - 1, uYRegSpace); iPreviousCubeIndexX &= 170; //170 = 128+32+8+2 iPreviousCubeIndexX >>= 1; @@ -388,7 +388,7 @@ namespace PolyVox } //Save the bitmask - pCurrentBitmask[uXRegSpace][uYRegSpace] = iCubeIndex; + pCurrentBitmask(uXRegSpace, uYRegSpace) = iCubeIndex; if(edgeTable[iCubeIndex] != 0) { @@ -415,7 +415,7 @@ namespace PolyVox 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 - const uint8_t iCubeIndex = pCurrentBitmask[uXRegSpace][uYRegSpace]; + const uint8_t iCubeIndex = pCurrentBitmask(uXRegSpace, uYRegSpace); /* Cube is entirely in/out of the surface */ if (edgeTable[iCubeIndex] == 0) @@ -461,7 +461,7 @@ namespace PolyVox surfaceVertex.data = uMaterial; 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(); } @@ -495,7 +495,7 @@ namespace PolyVox surfaceVertex.data = uMaterial; 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(); } @@ -528,7 +528,7 @@ namespace PolyVox surfaceVertex.data = uMaterial; 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(); } @@ -563,7 +563,7 @@ namespace PolyVox 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 - const uint8_t iCubeIndex = pPreviousBitmask[uXRegSpace][uYRegSpace]; + const uint8_t iCubeIndex = pPreviousBitmask(uXRegSpace, uYRegSpace); /* Cube is entirely in/out of the surface */ if (edgeTable[iCubeIndex] == 0) @@ -574,51 +574,51 @@ namespace PolyVox /* Find the vertices where the surface intersects the cube */ if (edgeTable[iCubeIndex] & 1) { - indlist[0] = m_pPreviousVertexIndicesX[uXRegSpace][uYRegSpace]; + indlist[0] = m_pPreviousVertexIndicesX(uXRegSpace, uYRegSpace); } if (edgeTable[iCubeIndex] & 2) { - indlist[1] = m_pPreviousVertexIndicesY[uXRegSpace+1][uYRegSpace]; + indlist[1] = m_pPreviousVertexIndicesY(uXRegSpace + 1, uYRegSpace); } if (edgeTable[iCubeIndex] & 4) { - indlist[2] = m_pPreviousVertexIndicesX[uXRegSpace][uYRegSpace+1]; + indlist[2] = m_pPreviousVertexIndicesX(uXRegSpace, uYRegSpace + 1); } if (edgeTable[iCubeIndex] & 8) { - indlist[3] = m_pPreviousVertexIndicesY[uXRegSpace][uYRegSpace]; + indlist[3] = m_pPreviousVertexIndicesY(uXRegSpace, uYRegSpace); } if (edgeTable[iCubeIndex] & 16) { - indlist[4] = m_pCurrentVertexIndicesX[uXRegSpace][uYRegSpace]; + indlist[4] = m_pCurrentVertexIndicesX(uXRegSpace, uYRegSpace); } if (edgeTable[iCubeIndex] & 32) { - indlist[5] = m_pCurrentVertexIndicesY[uXRegSpace+1][uYRegSpace]; + indlist[5] = m_pCurrentVertexIndicesY(uXRegSpace + 1, uYRegSpace); } if (edgeTable[iCubeIndex] & 64) { - indlist[6] = m_pCurrentVertexIndicesX[uXRegSpace][uYRegSpace+1]; + indlist[6] = m_pCurrentVertexIndicesX(uXRegSpace, uYRegSpace + 1); } if (edgeTable[iCubeIndex] & 128) { - indlist[7] = m_pCurrentVertexIndicesY[uXRegSpace][uYRegSpace]; + indlist[7] = m_pCurrentVertexIndicesY(uXRegSpace, uYRegSpace); } if (edgeTable[iCubeIndex] & 256) { - indlist[8] = m_pPreviousVertexIndicesZ[uXRegSpace][uYRegSpace]; + indlist[8] = m_pPreviousVertexIndicesZ(uXRegSpace, uYRegSpace); } if (edgeTable[iCubeIndex] & 512) { - indlist[9] = m_pPreviousVertexIndicesZ[uXRegSpace+1][uYRegSpace]; + indlist[9] = m_pPreviousVertexIndicesZ(uXRegSpace + 1, uYRegSpace); } if (edgeTable[iCubeIndex] & 1024) { - indlist[10] = m_pPreviousVertexIndicesZ[uXRegSpace+1][uYRegSpace+1]; + indlist[10] = m_pPreviousVertexIndicesZ(uXRegSpace + 1, uYRegSpace + 1); } 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) From ad73caf36873ff8fb0509f4f8ec81983f489c253 Mon Sep 17 00:00:00 2001 From: David Williams Date: Fri, 22 Aug 2014 15:49:30 +0200 Subject: [PATCH 09/16] Array2D now has private copy constructor and assignment operator to prevent accidental copying. --- library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h index b6713ae9..062e61e0 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h @@ -73,6 +73,10 @@ namespace PolyVox private: + // These are private to avoid accidental copying. + Array2D(const Array2D& rhs); + Array2D& operator=(const Array2D& rhs); + uint32_t m_uWidth; uint32_t m_uHeight; ElementType* m_pData; From 1fb82f40b300cd383011b3eb7b4288bbddc8ac6b Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 24 Aug 2014 11:51:45 +0200 Subject: [PATCH 10/16] Switched to C++11-style hiding of copy constructor and assignment operator. --- library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h index 062e61e0..3cac675c 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h @@ -39,6 +39,10 @@ namespace PolyVox m_pData = new ElementType[m_uWidth * m_uHeight]; } + // These are deleted to avoid accidental copying. + Array2D(const Array2D&) = delete; + Array2D& operator=(const Array2D&) = delete; + ~Array2D() { delete[] m_pData; @@ -73,10 +77,6 @@ namespace PolyVox private: - // These are private to avoid accidental copying. - Array2D(const Array2D& rhs); - Array2D& operator=(const Array2D& rhs); - uint32_t m_uWidth; uint32_t m_uHeight; ElementType* m_pData; From 083c65ecd53ad52acab9e8a6665d7938c415bc8d Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 24 Aug 2014 12:03:41 +0200 Subject: [PATCH 11/16] Added asserts. --- library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h index 3cac675c..751169c6 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h @@ -50,11 +50,13 @@ namespace PolyVox ElementType operator()(uint32_t x, uint32_t y) const { + POLYVOX_ASSERT((x < m_uWidth && y < m_uHeight), "Array access is out-of-range."); return m_pData[y * m_uWidth + x]; } ElementType& operator()(uint32_t x, uint32_t y) { + POLYVOX_ASSERT((x < m_uWidth && y < m_uHeight), "Array access is out-of-range."); return m_pData[y * m_uWidth + x]; } From 9a1c6784df99a6ccb826b407eb71acb9521bca98 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 24 Aug 2014 12:26:36 +0200 Subject: [PATCH 12/16] Steps towards making new array class be multidimensional. --- .../include/PolyVoxCore/Impl/Array2D.h | 56 +++++++++++-------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h index 751169c6..be383e98 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h @@ -26,22 +26,23 @@ distribution. namespace PolyVox { - template + template class Array2D { public: Array2D(uint32_t width, uint32_t height) - :m_uWidth(width) - , m_uHeight(height) - , m_pData(0) + :m_pData(0) { - m_pData = new ElementType[m_uWidth * m_uHeight]; + m_uDimensions[0] = width; + m_uDimensions[1] = height; + + initialize(); } // These are deleted to avoid accidental copying. - Array2D(const Array2D&) = delete; - Array2D& operator=(const Array2D&) = delete; + Array2D(const Array2D&) = delete; + Array2D& operator=(const Array2D&) = delete; ~Array2D() { @@ -50,14 +51,14 @@ namespace PolyVox ElementType operator()(uint32_t x, uint32_t y) const { - POLYVOX_ASSERT((x < m_uWidth && y < m_uHeight), "Array access is out-of-range."); - return m_pData[y * m_uWidth + x]; + POLYVOX_ASSERT((x < m_uDimensions[0] && y < m_uDimensions[1]), "Array access is out-of-range."); + return m_pData[y * m_uDimensions[0] + x]; } ElementType& operator()(uint32_t x, uint32_t y) { - POLYVOX_ASSERT((x < m_uWidth && y < m_uHeight), "Array access is out-of-range."); - return m_pData[y * m_uWidth + x]; + POLYVOX_ASSERT((x < m_uDimensions[0] && y < m_uDimensions[1]), "Array access is out-of-range."); + return m_pData[y * m_uDimensions[0] + x]; } ElementType* getRawData() @@ -67,7 +68,7 @@ namespace PolyVox size_t getNoOfElements() { - return m_uWidth * m_uHeight; + return m_uNoOfElements; } void swap(Array2D& other) @@ -79,27 +80,38 @@ namespace PolyVox private: - uint32_t m_uWidth; - uint32_t m_uHeight; + 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_pData = new ElementType[m_uNoOfElements]; + } + + uint32_t m_uDimensions[noOfDims]; + uint32_t m_uNoOfElements; ElementType* m_pData; }; ///A 2D Array of floats. - typedef Array2D Array2DFloat; + typedef Array2D<2, float> Array2DFloat; ///A 2D Array of doubles. - typedef Array2D Array2DDouble; + typedef Array2D<2, double> Array2DDouble; ///A 2D Array of signed 8-bit values. - typedef Array2D Array2DInt8; + typedef Array2D<2, int8_t> Array2DInt8; ///A 2D Array of unsigned 8-bit values. - typedef Array2D Array2DUint8; + typedef Array2D<2, uint8_t> Array2DUint8; ///A 2D Array of signed 16-bit values. - typedef Array2D Array2DInt16; + typedef Array2D<2, int16_t> Array2DInt16; ///A 2D Array of unsigned 16-bit values. - typedef Array2D Array2DUint16; + typedef Array2D<2, uint16_t> Array2DUint16; ///A 2D Array of signed 32-bit values. - typedef Array2D Array2DInt32; + typedef Array2D<2, int32_t> Array2DInt32; ///A 2D Array of unsigned 32-bit values. - typedef Array2D Array2DUint32; + typedef Array2D<2, uint32_t> Array2DUint32; } #endif //__PolyVox_Array2D_H__ \ No newline at end of file From 528873bcd3c100270cb68ba5ddb4a5265913d648 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 24 Aug 2014 21:54:59 +0200 Subject: [PATCH 13/16] Extended 'Array2D class to be multidimensional (will rename it shortly). --- .../PolyVoxCore/include/PolyVoxCore/Array.h | 8 +- .../include/PolyVoxCore/Impl/Array2D.h | 103 +++++++++++++++--- .../PolyVoxCore/PolyVoxForwardDeclarations.h | 8 +- tests/TestArray.cpp | 60 ++++++---- 4 files changed, 131 insertions(+), 48 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/Array.h b/library/PolyVoxCore/include/PolyVoxCore/Array.h index ae59524a..9ee935ba 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Array.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Array.h @@ -154,7 +154,7 @@ namespace PolyVox //Some handy typedefs ///A 1D Array of floats. - typedef Array<1,float> Array1DFloat; + /*typedef Array<1,float> Array1DFloat; ///A 1D Array of doubles. typedef Array<1,double> Array1DDouble; ///A 1D Array of signed 8-bit values. @@ -168,7 +168,7 @@ namespace PolyVox ///A 1D Array of signed 32-bit values. typedef Array<1,int32_t> Array1DInt32; ///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. /*typedef Array<2,float> Array2DFloat; @@ -188,7 +188,7 @@ namespace PolyVox typedef Array<2,uint32_t> Array2DUint32;*/ ///A 3D Array of floats. - typedef Array<3,float> Array3DFloat; + /*typedef Array<3,float> Array3DFloat; ///A 3D Array of doubles. typedef Array<3,double> Array3DDouble; ///A 3D Array of signed 8-bit values. @@ -202,7 +202,7 @@ namespace PolyVox ///A 3D Array of signed 32-bit values. typedef Array<3,int32_t> Array3DInt32; ///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" diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h index be383e98..6eaeace4 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h @@ -24,6 +24,10 @@ distribution. #ifndef __PolyVox_Array2D_H__ #define __PolyVox_Array2D_H__ +#include + +#include + namespace PolyVox { template @@ -31,51 +35,84 @@ namespace PolyVox { public: - Array2D(uint32_t width, uint32_t height) - :m_pData(0) + Array2D(uint32_t width) + :m_pElements(0) { + static_assert(noOfDims == 1, "This constructor can only be used with a one-dimensional array"); + + m_uDimensions[0] = width; + + initialize(); + } + + Array2D(uint32_t width, uint32_t height) + :m_pElements(0) + { + static_assert(noOfDims == 2, "This constructor can only be used with a two-dimensional array"); + m_uDimensions[0] = width; m_uDimensions[1] = height; initialize(); } + Array2D(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. Array2D(const Array2D&) = delete; Array2D& operator=(const Array2D&) = delete; ~Array2D() { - delete[] m_pData; + delete[] m_pElements; } - ElementType operator()(uint32_t x, uint32_t y) const + ElementType& operator()(uint32_t x) const { - POLYVOX_ASSERT((x < m_uDimensions[0] && y < m_uDimensions[1]), "Array access is out-of-range."); - return m_pData[y * m_uDimensions[0] + x]; + 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) + ElementType& operator()(uint32_t x, uint32_t y) const { - POLYVOX_ASSERT((x < m_uDimensions[0] && y < m_uDimensions[1]), "Array access is out-of-range."); - return m_pData[y * m_uDimensions[0] + x]; + 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[1] * m_uDimensions[1] + y * m_uDimensions[0] + x]; } ElementType* getRawData() { - return m_pData; + return m_pElements; } - size_t getNoOfElements() + uint32_t getNoOfElements() { return m_uNoOfElements; } void swap(Array2D& other) { - ElementType* temp = other.m_pData; - other.m_pData = m_pData; - m_pData = temp; + ElementType* temp = other.m_pElements; + other.m_pElements = m_pElements; + m_pElements = temp; } private: @@ -88,14 +125,31 @@ namespace PolyVox { m_uNoOfElements *= m_uDimensions[i]; } - m_pData = new ElementType[m_uNoOfElements]; + m_pElements = new ElementType[m_uNoOfElements]; } uint32_t m_uDimensions[noOfDims]; uint32_t m_uNoOfElements; - ElementType* m_pData; + ElementType* m_pElements; }; + ///A 1D Array of floats. + typedef Array2D<1, float> Array1DFloat; + ///A 1D Array of doubles. + typedef Array2D<1, double> Array1DDouble; + ///A 1D Array of signed 8-bit values. + typedef Array2D<1, int8_t> Array1DInt8; + ///A 1D Array of unsigned 8-bit values. + typedef Array2D<1, uint8_t> Array1DUint8; + ///A 1D Array of signed 16-bit values. + typedef Array2D<1, int16_t> Array1DInt16; + ///A 1D Array of unsigned 16-bit values. + typedef Array2D<1, uint16_t> Array1DUint16; + ///A 1D Array of signed 32-bit values. + typedef Array2D<1, int32_t> Array1DInt32; + ///A 1D Array of unsigned 32-bit values. + typedef Array2D<1, uint32_t> Array1DUint32; + ///A 2D Array of floats. typedef Array2D<2, float> Array2DFloat; ///A 2D Array of doubles. @@ -112,6 +166,23 @@ namespace PolyVox typedef Array2D<2, int32_t> Array2DInt32; ///A 2D Array of unsigned 32-bit values. typedef Array2D<2, uint32_t> Array2DUint32; + + ///A 3D Array of floats. + typedef Array2D<3, float> Array3DFloat; + ///A 3D Array of doubles. + typedef Array2D<3, double> Array3DDouble; + ///A 3D Array of signed 8-bit values. + typedef Array2D<3, int8_t> Array3DInt8; + ///A 3D Array of unsigned 8-bit values. + typedef Array2D<3, uint8_t> Array3DUint8; + ///A 3D Array of signed 16-bit values. + typedef Array2D<3, int16_t> Array3DInt16; + ///A 3D Array of unsigned 16-bit values. + typedef Array2D<3, uint16_t> Array3DUint16; + ///A 3D Array of signed 32-bit values. + typedef Array2D<3, int32_t> Array3DInt32; + ///A 3D Array of unsigned 32-bit values. + typedef Array2D<3, uint32_t> Array3DUint32; } #endif //__PolyVox_Array2D_H__ \ No newline at end of file diff --git a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h index 75ddf905..4c63906d 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h +++ b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h @@ -33,7 +33,7 @@ namespace PolyVox //////////////////////////////////////////////////////////////////////////////// // Array //////////////////////////////////////////////////////////////////////////////// - template class Array; + /*template class Array; typedef Array<1,float> Array1DFloat; typedef Array<1,double> Array1DDouble; @@ -42,7 +42,7 @@ namespace PolyVox typedef Array<1,int16_t> Array1DInt16; typedef Array<1,uint16_t> Array1DUint16; 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,double> Array2DDouble; @@ -53,14 +53,14 @@ namespace PolyVox typedef Array<2,int32_t> Array2DInt32; typedef Array<2,uint32_t> Array2DUint32;*/ - typedef Array<3,float> Array3DFloat; + /*typedef Array<3,float> Array3DFloat; typedef Array<3,double> Array3DDouble; typedef Array<3,int8_t> Array3DInt8; typedef Array<3,uint8_t> Array3DUint8; typedef Array<3,int16_t> Array3DInt16; typedef Array<3,uint16_t> Array3DUint16; typedef Array<3,int32_t> Array3DInt32; - typedef Array<3,uint32_t> Array3DUint32; + typedef Array<3,uint32_t> Array3DUint32;*/ //////////////////////////////////////////////////////////////////////////////// // BlockCompressor diff --git a/tests/TestArray.cpp b/tests/TestArray.cpp index 6d41aa6e..84d4bf14 100644 --- a/tests/TestArray.cpp +++ b/tests/TestArray.cpp @@ -33,22 +33,26 @@ using namespace PolyVox; void TestArray::testCArraySpeed() { - const int width = 128; - const int height = 128; + const int width = 32; + const int height = 32; + const int depth = 32; - int cArray[width][height]; + int cArray[width][height][depth]; QBENCHMARK { int ct = 1; int expectedTotal = 0; - for (int y = 0; y < height; y++) + for (int z = 0; z < depth; z++) { - for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) { - cArray[x][y] = ct; - expectedTotal += cArray[x][y]; - ct++; + for (int x = 0; x < width; x++) + { + cArray[x][y][z] = ct; + expectedTotal += cArray[x][y][z]; + ct++; + } } } } @@ -56,22 +60,26 @@ void TestArray::testCArraySpeed() void TestArray::testPolyVoxArraySpeed() { - const int width = 128; - const int height = 128; + const int width = 32; + const int height = 32; + const int depth = 32; - Array<2, int> polyvoxArray(ArraySizes(width)(height)); + Array<3, int> polyvoxArray(ArraySizes(width)(height)(depth)); QBENCHMARK { int ct = 1; int expectedTotal = 0; - for (int y = 0; y < height; y++) + for (int z = 0; z < depth; z++) { - for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) { - polyvoxArray[x][y] = ct; - expectedTotal += polyvoxArray[x][y]; - ct++; + for (int x = 0; x < width; x++) + { + polyvoxArray[x][y][z] = ct; + expectedTotal += polyvoxArray[x][y][z]; + ct++; + } } } } @@ -79,22 +87,26 @@ void TestArray::testPolyVoxArraySpeed() void TestArray::testPolyVoxArray2DSpeed() { - const int width = 128; - const int height = 128; + const int width = 32; + const int height = 32; + const int depth = 32; - Array2D polyvoxArray(width,height); + Array2D<3, int> polyvoxArray(width, height, depth); QBENCHMARK { int ct = 1; int expectedTotal = 0; - for (int y = 0; y < height; y++) + for (int z = 0; z < depth; z++) { - for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) { - polyvoxArray(x,y) = ct; - expectedTotal += polyvoxArray(x,y); - ct++; + for (int x = 0; x < width; x++) + { + polyvoxArray(x, y, z) = ct; + expectedTotal += polyvoxArray(x, y, z); + ct++; + } } } } From d49db280d549fafef0313c343bf82d76072fe607 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 24 Aug 2014 21:55:44 +0200 Subject: [PATCH 14/16] TestVolumeSubclass now uses Array2D instead of Array. --- tests/TestVolumeSubclass.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/TestVolumeSubclass.cpp b/tests/TestVolumeSubclass.cpp index 73351113..b8848c11 100644 --- a/tests/TestVolumeSubclass.cpp +++ b/tests/TestVolumeSubclass.cpp @@ -23,7 +23,8 @@ freely, subject to the following restrictions: #include "TestVolumeSubclass.h" -#include "PolyVoxCore/Array.h" +#include "PolyVoxCore/Impl/Array2D.h" + #include "PolyVoxCore/BaseVolume.h" #include "PolyVoxCore/CubicSurfaceExtractor.h" #include "PolyVoxCore/Material.h" @@ -62,8 +63,9 @@ public: /// Constructor for creating a fixed size volume. VolumeSubclass(const Region& regValid) :BaseVolume(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 ~VolumeSubclass() {}; @@ -97,7 +99,7 @@ public: POLYVOX_THROW(std::out_of_range, "Position is outside valid region"); } - return mVolumeData[uXPos][uYPos][uZPos]; + return mVolumeData(uXPos, uYPos, uZPos); } case WrapModes::Clamp: { @@ -108,13 +110,13 @@ public: uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX()); uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY()); uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ()); - return mVolumeData[uXPos][uYPos][uZPos]; + return mVolumeData(uXPos, uYPos, uZPos); } case WrapModes::Border: { if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos)) { - return mVolumeData[uXPos][uYPos][uZPos]; + return mVolumeData(uXPos, uYPos, uZPos); } else { @@ -123,7 +125,7 @@ public: } case WrapModes::AssumeValid: { - return mVolumeData[uXPos][uYPos][uZPos]; + return mVolumeData(uXPos, uYPos, uZPos); } default: { @@ -147,7 +149,7 @@ public: { if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos))) { - mVolumeData[uXPos][uYPos][uZPos] = tValue; + mVolumeData(uXPos, uYPos, uZPos) = tValue; return true; } else @@ -165,7 +167,7 @@ public: //void resize(const Region& regValidRegion); private: - Array<3, VoxelType> mVolumeData; + Array2D<3, VoxelType> mVolumeData; }; void TestVolumeSubclass::testExtractSurface() From d06dbdf054a66330df8c745a36dac21bdfe1f5b3 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 24 Aug 2014 22:30:50 +0200 Subject: [PATCH 15/16] Bit renaming. Old Array class is gone, and is replaced by the Array2D class which has also been renamed to Array. --- library/PolyVoxCore/CMakeLists.txt | 8 - .../include/PolyVoxCore/AStarPathfinder.h | 2 - .../AmbientOcclusionCalculator.inl | 2 +- .../PolyVoxCore/include/PolyVoxCore/Array.h | 279 +++++++-------- .../PolyVoxCore/include/PolyVoxCore/Array.inl | 335 ------------------ .../include/PolyVoxCore/ArraySizes.h | 77 ---- .../PolyVoxCore/CubicSurfaceExtractor.inl | 14 +- .../include/PolyVoxCore/Impl/Array2D.h | 188 ---------- .../include/PolyVoxCore/Impl/ArraySizesImpl.h | 63 ---- .../PolyVoxCore/Impl/ArraySizesImpl.inl | 46 --- .../include/PolyVoxCore/Impl/SubArray.h | 90 ----- .../include/PolyVoxCore/Impl/SubArray.inl | 92 ----- .../MarchingCubesSurfaceExtractor.h | 2 +- library/PolyVoxCore/source/ArraySizes.cpp | 57 --- tests/TestAmbientOcclusionGenerator.cpp | 12 +- tests/TestArray.cpp | 41 +-- tests/TestArray.h | 1 - tests/TestVolumeSubclass.cpp | 4 +- 18 files changed, 155 insertions(+), 1158 deletions(-) delete mode 100644 library/PolyVoxCore/include/PolyVoxCore/Array.inl delete mode 100644 library/PolyVoxCore/include/PolyVoxCore/ArraySizes.h delete mode 100644 library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h delete mode 100644 library/PolyVoxCore/include/PolyVoxCore/Impl/ArraySizesImpl.h delete mode 100644 library/PolyVoxCore/include/PolyVoxCore/Impl/ArraySizesImpl.inl delete mode 100644 library/PolyVoxCore/include/PolyVoxCore/Impl/SubArray.h delete mode 100644 library/PolyVoxCore/include/PolyVoxCore/Impl/SubArray.inl delete mode 100644 library/PolyVoxCore/source/ArraySizes.cpp diff --git a/library/PolyVoxCore/CMakeLists.txt b/library/PolyVoxCore/CMakeLists.txt index ed06c3c6..2f115630 100644 --- a/library/PolyVoxCore/CMakeLists.txt +++ b/library/PolyVoxCore/CMakeLists.txt @@ -24,7 +24,6 @@ PROJECT(PolyVoxCore) #Projects source files SET(CORE_SRC_FILES - source/ArraySizes.cpp source/AStarPathfinder.cpp source/Region.cpp ) @@ -34,8 +33,6 @@ SET(CORE_INC_FILES include/PolyVoxCore/AmbientOcclusionCalculator.h include/PolyVoxCore/AmbientOcclusionCalculator.inl include/PolyVoxCore/Array.h - include/PolyVoxCore/Array.inl - include/PolyVoxCore/ArraySizes.h include/PolyVoxCore/AStarPathfinder.h include/PolyVoxCore/AStarPathfinder.inl include/PolyVoxCore/BaseVolume.h @@ -108,9 +105,6 @@ SET(IMPL_SRC_FILES ) SET(IMPL_INC_FILES - include/PolyVoxCore/Impl/Array2D.h - include/PolyVoxCore/Impl/ArraySizesImpl.h - include/PolyVoxCore/Impl/ArraySizesImpl.inl include/PolyVoxCore/Impl/AStarPathfinderImpl.h include/PolyVoxCore/Impl/Config.h include/PolyVoxCore/Impl/ErrorHandling.h @@ -119,8 +113,6 @@ SET(IMPL_INC_FILES include/PolyVoxCore/Impl/MinizWrapper.h include/PolyVoxCore/Impl/RandomUnitVectors.h include/PolyVoxCore/Impl/RandomVectors.h - include/PolyVoxCore/Impl/SubArray.h - include/PolyVoxCore/Impl/SubArray.inl include/PolyVoxCore/Impl/Timer.h include/PolyVoxCore/Impl/TypeDef.h include/PolyVoxCore/Impl/Utility.h diff --git a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h index 7b86d8bc..88b22374 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h +++ b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h @@ -27,8 +27,6 @@ freely, subject to the following restrictions: #include "Impl/AStarPathfinderImpl.h" #include "Impl/TypeDef.h" -#include "PolyVoxCore/Array.h" - #include #include #include //For runtime_error diff --git a/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.inl b/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.inl index 82c266f3..c64c6d22 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.inl @@ -128,7 +128,7 @@ namespace PolyVox POLYVOX_ASSERT((fVisibility >= 0.0f) && (fVisibility <= 1.0f), "Visibility value out of range."); } - (*arrayResult)[z / iRatioZ][y / iRatioY][x / iRatioX] = static_cast(255.0f * fVisibility); + (*arrayResult)(z / iRatioZ, y / iRatioY, x / iRatioX) = static_cast(255.0f * fVisibility); } } } diff --git a/library/PolyVoxCore/include/PolyVoxCore/Array.h b/library/PolyVoxCore/include/PolyVoxCore/Array.h index 9ee935ba..4ec0f616 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Array.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Array.h @@ -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 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 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. +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. +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. +3. This notice may not be removed or altered from any source +distribution. *******************************************************************************/ #ifndef __PolyVox_Array_H__ #define __PolyVox_Array_H__ -#include "Impl/SubArray.h" +#include -#include "PolyVoxCore/ArraySizes.h" //Not strictly required, but convienient +#include 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 class Array { public: - ///Constructor - Array(); - ///Constructor - Array(const uint32_t (&pDimensions)[noOfDims]); - ///Destructor - ~Array(); - ///Subarray access - SubArray operator[](uint32_t uIndex); - ///Subarray access - const SubArray operator[](uint32_t uIndex) const; + Array(uint32_t width) + :m_pElements(0) + { + static_assert(noOfDims == 1, "This constructor can only be used with a one-dimensional array"); - ///Gets the total number of elements in this array - uint32_t getNoOfElements(void) const; - ///Gets a pointer to the first element of the array - ElementType* getRawData(void) const; + m_uDimensions[0] = width; - ///Resize the array to the specified dimensions - void resize(const uint32_t (&pDimensions)[noOfDims]); - ///Swaps the contents of this array with the one specified - void swap(Array& rhs); - ///Get the size of the Array along the specified dimension - uint32_t getDimension(uint32_t uDimension); + initialize(); + } + + Array(uint32_t width, uint32_t height) + :m_pElements(0) + { + 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(const Array&) = delete; + Array& operator=(const Array&) = 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[1] * 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: - Array(const Array& rhs); - Array& operator=(const Array& 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_pDimensions; - uint32_t * m_pOffsets; + uint32_t m_uDimensions[noOfDims]; uint32_t m_uNoOfElements; - ElementType * m_pElements; + ElementType* m_pElements; }; - template - 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 - class Array<0, ElementType> - { - //Zero dimensional array is meaningless. - }; - - //Some handy typedefs ///A 1D Array of floats. - /*typedef Array<1,float> Array1DFloat; + typedef Array<1, float> Array1DFloat; ///A 1D Array of doubles. - typedef Array<1,double> Array1DDouble; + typedef Array<1, double> Array1DDouble; ///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. - typedef Array<1,uint8_t> Array1DUint8; + typedef Array<1, uint8_t> Array1DUint8; ///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. - typedef Array<1,uint16_t> Array1DUint16; + typedef Array<1, uint16_t> Array1DUint16; ///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. - typedef Array<1,uint32_t> Array1DUint32;*/ + typedef Array<1, uint32_t> Array1DUint32; ///A 2D Array of floats. - /*typedef Array<2,float> Array2DFloat; + typedef Array<2, float> Array2DFloat; ///A 2D Array of doubles. - typedef Array<2,double> Array2DDouble; + typedef Array<2, double> Array2DDouble; ///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. - typedef Array<2,uint8_t> Array2DUint8; + typedef Array<2, uint8_t> Array2DUint8; ///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. - typedef Array<2,uint16_t> Array2DUint16; + typedef Array<2, uint16_t> Array2DUint16; ///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. - typedef Array<2,uint32_t> Array2DUint32;*/ + typedef Array<2, uint32_t> Array2DUint32; ///A 3D Array of floats. - /*typedef Array<3,float> Array3DFloat; + typedef Array<3, float> Array3DFloat; ///A 3D Array of doubles. - typedef Array<3,double> Array3DDouble; + typedef Array<3, double> Array3DDouble; ///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. - typedef Array<3,uint8_t> Array3DUint8; + typedef Array<3, uint8_t> Array3DUint8; ///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. - typedef Array<3,uint16_t> Array3DUint16; + typedef Array<3, uint16_t> Array3DUint16; ///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. - typedef Array<3,uint32_t> Array3DUint32;*/ -}//namespace PolyVox + typedef Array<3, uint32_t> Array3DUint32; +} -#include "PolyVoxCore/Array.inl" - -#endif +#endif //__PolyVox_Array_H__ \ No newline at end of file diff --git a/library/PolyVoxCore/include/PolyVoxCore/Array.inl b/library/PolyVoxCore/include/PolyVoxCore/Array.inl deleted file mode 100644 index 53f428ac..00000000 --- a/library/PolyVoxCore/include/PolyVoxCore/Array.inl +++ /dev/null @@ -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 - Array::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 - Array::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 - Array::~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 - SubArray Array::operator[](uint32_t uIndex) - { - POLYVOX_THROW_IF(uIndex >= m_pDimensions[0], std::out_of_range, "Array index out of range"); - - return - SubArray(&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 - const SubArray Array::operator[](uint32_t uIndex) const - { - POLYVOX_THROW_IF(uIndex >= m_pDimensions[0], std::out_of_range, "Array index out of range"); - - return - SubArray(&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 Array::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 - ElementType* Array::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 - void Array::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; ii; 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 - void Array::swap(Array& 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 Array::getDimension(uint32_t uDimension) - { - POLYVOX_THROW_IF(uDimension >= noOfDims, std::out_of_range, "Array dimension out of range"); - - return m_pDimensions[uDimension]; - } - - template - Array::Array(const Array& 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 - Array& Array::operator=(const Array& rhs) - { - //Not implemented - POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!"); - - return *this; - } - - template - void Array::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 - Array<1, ElementType>::Array() - : m_pElements(0) - ,m_pDimensions(0) - { - } - - template - Array<1, ElementType>::Array(const uint32_t (&pDimensions)[1]) - : m_pElements(0) - ,m_pDimensions(0) - { - resize(pDimensions); - } - - template - Array<1, ElementType>::~Array() - { - deallocate(); - } - - template - 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 - 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 - uint32_t Array<1, ElementType>::getNoOfElements(void) const - { - return m_pDimensions[0]; - } - - template - ElementType* Array<1, ElementType>::getRawData(void) const - { - return m_pElements; - } - - template - 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 - 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 - 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 - 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 - void Array<1, ElementType>::deallocate(void) - { - delete[] m_pDimensions; - m_pDimensions = 0; - delete[] m_pElements; - m_pElements = 0; - } -}//namespace PolyVox diff --git a/library/PolyVoxCore/include/PolyVoxCore/ArraySizes.h b/library/PolyVoxCore/include/PolyVoxCore/ArraySizes.h deleted file mode 100644 index 93bd6d0c..00000000 --- a/library/PolyVoxCore/include/PolyVoxCore/ArraySizes.h +++ /dev/null @@ -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__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl index edf8ea7a..bcf4247d 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl @@ -43,6 +43,8 @@ namespace PolyVox ,m_bMergeQuads(bMergeQuads) ,m_eWrapMode(eWrapMode) ,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; @@ -59,12 +61,12 @@ namespace PolyVox Timer timer; m_meshCurrent->clear(); - uint32_t uArrayWidth = m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2; - uint32_t uArrayHeight = m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2; + //uint32_t uArrayWidth = m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2; + //uint32_t uArrayHeight = m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2; - uint32_t arraySize[3]= {uArrayWidth, uArrayHeight, MaxVerticesPerPosition}; - m_previousSliceVertices.resize(arraySize); - m_currentSliceVertices.resize(arraySize); + //uint32_t arraySize[3]= {uArrayWidth, uArrayHeight, MaxVerticesPerPosition}; + //m_previousSliceVertices.resize(arraySize); + //m_currentSliceVertices.resize(arraySize); memset(m_previousSliceVertices.getRawData(), 0xff, m_previousSliceVertices.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++) { - IndexAndMaterial& rEntry = existingVertices[uX][uY][ct]; + IndexAndMaterial& rEntry = existingVertices(uX, uY, ct); if(rEntry.iIndex == -1) { diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h deleted file mode 100644 index 6eaeace4..00000000 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Array2D.h +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* -Copyright (c) 2005-20014 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_Array2D_H__ -#define __PolyVox_Array2D_H__ - -#include - -#include - -namespace PolyVox -{ - template - class Array2D - { - public: - - Array2D(uint32_t width) - :m_pElements(0) - { - static_assert(noOfDims == 1, "This constructor can only be used with a one-dimensional array"); - - m_uDimensions[0] = width; - - initialize(); - } - - Array2D(uint32_t width, uint32_t height) - :m_pElements(0) - { - static_assert(noOfDims == 2, "This constructor can only be used with a two-dimensional array"); - - m_uDimensions[0] = width; - m_uDimensions[1] = height; - - initialize(); - } - - Array2D(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. - Array2D(const Array2D&) = delete; - Array2D& operator=(const Array2D&) = delete; - - ~Array2D() - { - 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[1] * m_uDimensions[1] + y * m_uDimensions[0] + x]; - } - - ElementType* getRawData() - { - return m_pElements; - } - - uint32_t getNoOfElements() - { - return m_uNoOfElements; - } - - void swap(Array2D& other) - { - ElementType* temp = other.m_pElements; - other.m_pElements = m_pElements; - m_pElements = temp; - } - - private: - - 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]; - } - - uint32_t m_uDimensions[noOfDims]; - uint32_t m_uNoOfElements; - ElementType* m_pElements; - }; - - ///A 1D Array of floats. - typedef Array2D<1, float> Array1DFloat; - ///A 1D Array of doubles. - typedef Array2D<1, double> Array1DDouble; - ///A 1D Array of signed 8-bit values. - typedef Array2D<1, int8_t> Array1DInt8; - ///A 1D Array of unsigned 8-bit values. - typedef Array2D<1, uint8_t> Array1DUint8; - ///A 1D Array of signed 16-bit values. - typedef Array2D<1, int16_t> Array1DInt16; - ///A 1D Array of unsigned 16-bit values. - typedef Array2D<1, uint16_t> Array1DUint16; - ///A 1D Array of signed 32-bit values. - typedef Array2D<1, int32_t> Array1DInt32; - ///A 1D Array of unsigned 32-bit values. - typedef Array2D<1, uint32_t> Array1DUint32; - - ///A 2D Array of floats. - typedef Array2D<2, float> Array2DFloat; - ///A 2D Array of doubles. - typedef Array2D<2, double> Array2DDouble; - ///A 2D Array of signed 8-bit values. - typedef Array2D<2, int8_t> Array2DInt8; - ///A 2D Array of unsigned 8-bit values. - typedef Array2D<2, uint8_t> Array2DUint8; - ///A 2D Array of signed 16-bit values. - typedef Array2D<2, int16_t> Array2DInt16; - ///A 2D Array of unsigned 16-bit values. - typedef Array2D<2, uint16_t> Array2DUint16; - ///A 2D Array of signed 32-bit values. - typedef Array2D<2, int32_t> Array2DInt32; - ///A 2D Array of unsigned 32-bit values. - typedef Array2D<2, uint32_t> Array2DUint32; - - ///A 3D Array of floats. - typedef Array2D<3, float> Array3DFloat; - ///A 3D Array of doubles. - typedef Array2D<3, double> Array3DDouble; - ///A 3D Array of signed 8-bit values. - typedef Array2D<3, int8_t> Array3DInt8; - ///A 3D Array of unsigned 8-bit values. - typedef Array2D<3, uint8_t> Array3DUint8; - ///A 3D Array of signed 16-bit values. - typedef Array2D<3, int16_t> Array3DInt16; - ///A 3D Array of unsigned 16-bit values. - typedef Array2D<3, uint16_t> Array3DUint16; - ///A 3D Array of signed 32-bit values. - typedef Array2D<3, int32_t> Array3DInt32; - ///A 3D Array of unsigned 32-bit values. - typedef Array2D<3, uint32_t> Array3DUint32; -} - -#endif //__PolyVox_Array2D_H__ \ No newline at end of file diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/ArraySizesImpl.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/ArraySizesImpl.h deleted file mode 100644 index 3a65c217..00000000 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/ArraySizesImpl.h +++ /dev/null @@ -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 - -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 - class ArraySizesImpl - { - typedef const uint32_t (&UIntArrayN)[N]; - - friend class ArraySizes; - friend class ArraySizesImpl; - - public: - ArraySizesImpl 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__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/ArraySizesImpl.inl b/library/PolyVoxCore/include/PolyVoxCore/Impl/ArraySizesImpl.inl deleted file mode 100644 index 13836476..00000000 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/ArraySizesImpl.inl +++ /dev/null @@ -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 - -namespace PolyVox -{ - template - ArraySizesImpl ArraySizesImpl::operator () (uint32_t uSize) - { - return ArraySizesImpl(m_pSizes, uSize); - } - - template - ArraySizesImpl::operator UIntArrayN () const - { - return m_pSizes; - } - - template - ArraySizesImpl::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 diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/SubArray.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/SubArray.h deleted file mode 100644 index 3e70a02c..00000000 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/SubArray.h +++ /dev/null @@ -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 - -namespace PolyVox -{ - template 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 - class SubArray - { - friend class Array; - friend class SubArray; - - public: - SubArray operator [](uint32_t uIndex); - - const SubArray operator [](uint32_t uIndex) const; - - private: - SubArray(ElementType * pElements, uint32_t * pDimensions, uint32_t * pOffsets); - - uint32_t * m_pDimensions; - uint32_t * m_pOffsets; - uint32_t m_uNoOfElements; - ElementType * m_pElements; - }; - - template - 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 - class SubArray<0, ElementType> - { - //Zero dimensional subarray is meaningless. - }; -}//namespace PolyVox - -#include "PolyVoxCore/Impl/SubArray.inl" - -#endif //__PolyVox_SubArray_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/SubArray.inl b/library/PolyVoxCore/include/PolyVoxCore/Impl/SubArray.inl deleted file mode 100644 index 81c526c3..00000000 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/SubArray.inl +++ /dev/null @@ -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 - SubArray SubArray::operator[](uint32_t uIndex) - { - if(uIndex >= m_pDimensions[0]) - { - POLYVOX_THROW(std::out_of_range, "Array index out of range"); - } - - return - SubArray(&m_pElements[uIndex*m_pOffsets[0]], - m_pDimensions+1, m_pOffsets+1); - } - - template - const SubArray SubArray::operator[](uint32_t uIndex) const - { - if(uIndex >= m_pDimensions[0]) - { - POLYVOX_THROW(std::out_of_range, "Array index out of range"); - } - - return - SubArray(&m_pElements[uIndex*m_pOffsets[0]], - m_pDimensions+1, m_pOffsets+1); - } - - template - SubArray::SubArray(ElementType * pElements, uint32_t * pDimensions, uint32_t * pOffsets) - :m_pDimensions(pDimensions) - ,m_pOffsets(pOffsets) - ,m_uNoOfElements(0) - ,m_pElements(pElements) - { - } - - - template - 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 - 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 - SubArray<1, ElementType>::SubArray(ElementType * pElements, uint32_t * pDimensions, uint32_t * /*pOffsets*/) - :m_pDimensions(pDimensions) - ,m_pElements(pElements) - { - } -}//namespace PolyVox diff --git a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h index 62ccbff6..cf42800e 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h @@ -27,7 +27,7 @@ freely, subject to the following restrictions: #include "Impl/MarchingCubesTables.h" #include "Impl/TypeDef.h" -#include "PolyVoxCore/Impl/Array2D.h" +#include "PolyVoxCore/Array.h" #include "PolyVoxCore/BaseVolume.h" //For wrap modes... should move these? #include "PolyVoxCore/Mesh.h" #include "PolyVoxCore/DefaultMarchingCubesController.h" diff --git a/library/PolyVoxCore/source/ArraySizes.cpp b/library/PolyVoxCore/source/ArraySizes.cpp deleted file mode 100644 index 52755a73..00000000 --- a/library/PolyVoxCore/source/ArraySizes.cpp +++ /dev/null @@ -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 - -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; - } -} diff --git a/tests/TestAmbientOcclusionGenerator.cpp b/tests/TestAmbientOcclusionGenerator.cpp index 667acce4..cb077ec2 100644 --- a/tests/TestAmbientOcclusionGenerator.cpp +++ b/tests/TestAmbientOcclusionGenerator.cpp @@ -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. 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 IsVoxelTransparent isVoxelTransparent; @@ -78,11 +78,11 @@ void TestAmbientOcclusionGenerator::testExecute() //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. - QCOMPARE(static_cast(ambientOcclusionResult[16][ 0][16]), 178); - QCOMPARE(static_cast(ambientOcclusionResult[16][ 8][16]), 109); - QCOMPARE(static_cast(ambientOcclusionResult[16][16][16]), 103); - QCOMPARE(static_cast(ambientOcclusionResult[16][24][16]), 123); - QCOMPARE(static_cast(ambientOcclusionResult[16][31][16]), 173); + QCOMPARE(static_cast(ambientOcclusionResult(16, 0, 16)), 178); + QCOMPARE(static_cast(ambientOcclusionResult(16, 8, 16)), 109); + QCOMPARE(static_cast(ambientOcclusionResult(16, 16, 16)), 103); + QCOMPARE(static_cast(ambientOcclusionResult(16, 24, 16)), 123); + QCOMPARE(static_cast(ambientOcclusionResult(16, 31, 16)), 173); //Just run a quick test to make sure that it compiles when taking a function pointer calculateAmbientOcclusion(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 8, &isVoxelTransparentFunction); diff --git a/tests/TestArray.cpp b/tests/TestArray.cpp index 84d4bf14..359a2abf 100644 --- a/tests/TestArray.cpp +++ b/tests/TestArray.cpp @@ -25,8 +25,6 @@ freely, subject to the following restrictions: #include "PolyVoxCore/Array.h" -#include "PolyVoxCore/Impl/Array2D.h" - #include using namespace PolyVox; @@ -64,34 +62,7 @@ void TestArray::testPolyVoxArraySpeed() const int height = 32; const int depth = 32; - Array<3, int> polyvoxArray(ArraySizes(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::testPolyVoxArray2DSpeed() -{ - const int width = 32; - const int height = 32; - const int depth = 32; - - Array2D<3, int> polyvoxArray(width, height, depth); + Array<3, int> polyvoxArray(width, height, depth); QBENCHMARK { @@ -118,7 +89,7 @@ void TestArray::testReadWrite() int height = 10; int depth = 20; - Array<3, int> myArray(ArraySizes(width)(height)(depth)); + Array<3, int> myArray(width, height, depth); int ct = 1; int expectedTotal = 0; @@ -128,8 +99,8 @@ void TestArray::testReadWrite() { for(int x = 0; x < width; x++) { - myArray[x][y][z] = ct; - expectedTotal += myArray[x][y][z]; + myArray(x, y, z) = ct; + expectedTotal += myArray(x, y, z); ct++; } } @@ -143,8 +114,8 @@ void TestArray::testReadWrite() { for(int x = 0; x < width; x++) { - QCOMPARE(myArray[x][y][z], ct); - total += myArray[x][y][z]; + QCOMPARE(myArray(x, y, z), ct); + total += myArray(x, y, z); ct++; } } diff --git a/tests/TestArray.h b/tests/TestArray.h index bd5425a6..2d3e5951 100644 --- a/tests/TestArray.h +++ b/tests/TestArray.h @@ -33,7 +33,6 @@ class TestArray: public QObject private slots: void testCArraySpeed(); void testPolyVoxArraySpeed(); - void testPolyVoxArray2DSpeed(); void testReadWrite(); }; diff --git a/tests/TestVolumeSubclass.cpp b/tests/TestVolumeSubclass.cpp index b8848c11..1db0065e 100644 --- a/tests/TestVolumeSubclass.cpp +++ b/tests/TestVolumeSubclass.cpp @@ -23,7 +23,7 @@ freely, subject to the following restrictions: #include "TestVolumeSubclass.h" -#include "PolyVoxCore/Impl/Array2D.h" +#include "PolyVoxCore/Array.h" #include "PolyVoxCore/BaseVolume.h" #include "PolyVoxCore/CubicSurfaceExtractor.h" @@ -167,7 +167,7 @@ public: //void resize(const Region& regValidRegion); private: - Array2D<3, VoxelType> mVolumeData; + Array<3, VoxelType> mVolumeData; }; void TestVolumeSubclass::testExtractSurface() From 25860122b06062c562980eedcf35a172c1120c5c Mon Sep 17 00:00:00 2001 From: David Williams Date: Mon, 25 Aug 2014 23:07:29 +0200 Subject: [PATCH 16/16] Fixed incorrect array indexing. --- library/PolyVoxCore/include/PolyVoxCore/Array.h | 2 +- tests/TestArray.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/Array.h b/library/PolyVoxCore/include/PolyVoxCore/Array.h index 4ec0f616..276a4f1e 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Array.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Array.h @@ -95,7 +95,7 @@ namespace PolyVox { 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[1] * m_uDimensions[1] + y * m_uDimensions[0] + x]; + return m_pElements[z * m_uDimensions[0] * m_uDimensions[1] + y * m_uDimensions[0] + x]; } uint32_t getDimension(uint32_t dimension) diff --git a/tests/TestArray.cpp b/tests/TestArray.cpp index 359a2abf..67e0143b 100644 --- a/tests/TestArray.cpp +++ b/tests/TestArray.cpp @@ -31,9 +31,9 @@ using namespace PolyVox; void TestArray::testCArraySpeed() { - const int width = 32; + const int width = 64; const int height = 32; - const int depth = 32; + const int depth = 16; int cArray[width][height][depth]; @@ -58,9 +58,9 @@ void TestArray::testCArraySpeed() void TestArray::testPolyVoxArraySpeed() { - const int width = 32; + const int width = 64; const int height = 32; - const int depth = 32; + const int depth = 16; Array<3, int> polyvoxArray(width, height, depth);