diff --git a/CMakeLists.txt b/CMakeLists.txt index cba5599e..6ff798d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,9 @@ endif() IF(CMAKE_COMPILER_IS_GNUCXX) #Maybe "OR MINGW" ADD_DEFINITIONS(-std=c++0x) #Enable C++0x mode ENDIF() +if(CMAKE_CXX_COMPILER MATCHES "clang") + ADD_DEFINITIONS(-std=c++0x) #Enable C++0x mode +endif() ADD_SUBDIRECTORY(library) diff --git a/documentation/_extensions/sphinxcontrib/doxylink.py b/documentation/_extensions/sphinxcontrib/doxylink.py index 4d4039a8..9542b6d0 100644 --- a/documentation/_extensions/sphinxcontrib/doxylink.py +++ b/documentation/_extensions/sphinxcontrib/doxylink.py @@ -10,7 +10,7 @@ from docutils import nodes, utils from sphinx.util.nodes import split_explicit_title from sphinx.util.console import bold, standout -from parsing import normalise, ParseException +from .parsing import normalise, ParseException def find_url(doc, symbol): """ @@ -156,7 +156,7 @@ def parse_tag_file(doc): else: mapping[member_symbol] = {'kind' : kind, 'arglist' : {normalised_arglist : anchor_link}} else: - print 'Skipping %s %s%s. Error reported from parser was: %s' % (old_tuple[2], old_tuple[0], old_tuple[1], normalised_tuple[0]) + print('Skipping %s %s%s. Error reported from parser was: %s' % (old_tuple[2], old_tuple[0], old_tuple[1], normalised_tuple[0])) #from pprint import pprint; pprint(mapping) return mapping diff --git a/documentation/_extensions/sphinxcontrib/parsing.py b/documentation/_extensions/sphinxcontrib/parsing.py index 4e42f44b..a110e067 100644 --- a/documentation/_extensions/sphinxcontrib/parsing.py +++ b/documentation/_extensions/sphinxcontrib/parsing.py @@ -94,7 +94,7 @@ def normalise(symbol): arglist_input_string = arglist_input_string[:closing_bracket_location+1] except ValueError: #This shouldn't happen. - print 'Could not find closing bracket in %s' % arglist_input_string + print('Could not find closing bracket in %s' % arglist_input_string) raise try: diff --git a/examples/Basic/OpenGLWidget.cpp b/examples/Basic/OpenGLWidget.cpp index d0f4adc0..f33a8c7c 100644 --- a/examples/Basic/OpenGLWidget.cpp +++ b/examples/Basic/OpenGLWidget.cpp @@ -149,4 +149,4 @@ void OpenGLWidget::mouseMoveEvent(QMouseEvent* event) m_LastFrameMousePos = m_CurrentMousePos; update(); -} \ No newline at end of file +} diff --git a/examples/Basic/OpenGLWidget.h b/examples/Basic/OpenGLWidget.h index 199a33ed..011b9734 100644 --- a/examples/Basic/OpenGLWidget.h +++ b/examples/Basic/OpenGLWidget.h @@ -64,4 +64,4 @@ private: int m_yRotation; }; -#endif //__BasicExample_OpenGLWidget_H__ \ No newline at end of file +#endif //__BasicExample_OpenGLWidget_H__ diff --git a/examples/Basic/main.cpp b/examples/Basic/main.cpp index 7da7d7cd..309b0eda 100644 --- a/examples/Basic/main.cpp +++ b/examples/Basic/main.cpp @@ -50,21 +50,26 @@ void createSphereInVolume(SimpleVolume& volData, float fR //And compute how far the current position is from the center of the volume float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length(); + uint8_t uDensity = 0; + uint8_t uMaterial = 0; + //If the current voxel is less than 'radius' units from the center then we make it solid. if(fDistToCenter <= fRadius) { //Our new density value - uint8_t uDensity = VoxelTypeTraits::MaxDensity; - - //Get the old voxel - MaterialDensityPair44 voxel = volData.getVoxelAt(x,y,z); - - //Modify the density - voxel.setDensity(uDensity); - - //Wrte the voxel value into the volume - volData.setVoxelAt(x, y, z, voxel); + uDensity = VoxelTypeTraits::maxDensity(); + uMaterial = 1; } + + //Get the old voxel + MaterialDensityPair44 voxel = volData.getVoxelAt(x,y,z); + + //Modify the density and material + voxel.setDensity(uDensity); + voxel.setMaterial(uMaterial); + + //Wrte the voxel value into the volume + volData.setVoxelAt(x, y, z, voxel); } } } diff --git a/examples/OpenGL/OpenGLWidget.cpp b/examples/OpenGL/OpenGLWidget.cpp index 7af04d61..f709d9b2 100644 --- a/examples/OpenGL/OpenGLWidget.cpp +++ b/examples/OpenGL/OpenGLWidget.cpp @@ -248,4 +248,4 @@ void OpenGLWidget::setupProjectionMatrix(void) float aspect = static_cast(width()) / static_cast(height()); glOrtho(frustumSize*aspect, -frustumSize*aspect, frustumSize, -frustumSize, 1.0, 5000); -} \ No newline at end of file +} diff --git a/examples/OpenGL/OpenGLWidget.h b/examples/OpenGL/OpenGLWidget.h index 9ffd35a6..2a808b4b 100644 --- a/examples/OpenGL/OpenGLWidget.h +++ b/examples/OpenGL/OpenGLWidget.h @@ -80,4 +80,4 @@ class OpenGLWidget : public QGLWidget unsigned int m_uVolumeDepthInRegions; }; -#endif //__PolyVox_OpenGLWidget_H__ \ No newline at end of file +#endif //__PolyVox_OpenGLWidget_H__ diff --git a/examples/OpenGL/Shapes.cpp b/examples/OpenGL/Shapes.cpp index 949523ac..36fbd5f7 100644 --- a/examples/OpenGL/Shapes.cpp +++ b/examples/OpenGL/Shapes.cpp @@ -30,7 +30,7 @@ using namespace PolyVox; void createSphereInVolume(LargeVolume& volData, float fRadius, uint8_t uValue) { //This vector hold the position of the center of the volume - Vector3DInt32 v3dVolCenter = (volData.getEnclosingRegion().getUpperCorner() - volData.getEnclosingRegion().getLowerCorner()) / 2; + Vector3DInt32 v3dVolCenter = (volData.getEnclosingRegion().getUpperCorner() - volData.getEnclosingRegion().getLowerCorner()) / static_cast(2); //This three-level for loop iterates over every voxel in the volume for (int z = 0; z < volData.getWidth(); z++) @@ -48,7 +48,7 @@ void createSphereInVolume(LargeVolume& volData, float fRa //then we make it solid, otherwise we make it empty space. if(fDistToCenter <= fRadius) { - //volData.setVoxelAt(x,y,z, MaterialDensityPair44(uValue, uValue > 0 ? VoxelTypeTraits::MaxDensity : VoxelTypeTraits::MinDensity)); + volData.setVoxelAt(x,y,z, MaterialDensityPair44(uValue, uValue > 0 ? VoxelTypeTraits::maxDensity() : VoxelTypeTraits::minDensity())); } } } @@ -57,8 +57,8 @@ void createSphereInVolume(LargeVolume& volData, float fRa void createCubeInVolume(LargeVolume& volData, Vector3DInt32 lowerCorner, Vector3DInt32 upperCorner, uint8_t uValue) { - int maxDen = VoxelTypeTraits::MaxDensity; - int minDen = VoxelTypeTraits::MinDensity; + int maxDen = VoxelTypeTraits::maxDensity(); + int minDen = VoxelTypeTraits::minDensity(); //This three-level for loop iterates over every voxel between the specified corners for (int z = lowerCorner.getZ(); z <= upperCorner.getZ(); z++) { diff --git a/examples/OpenGL/main.cpp b/examples/OpenGL/main.cpp index 238fe113..00b4cb5b 100644 --- a/examples/OpenGL/main.cpp +++ b/examples/OpenGL/main.cpp @@ -97,9 +97,9 @@ int main(int argc, char *argv[]) createCubeInVolume(volData, Vector3DInt32(midPos+1, minPos, midPos+1), Vector3DInt32(maxPos, midPos-1, maxPos), 0); createCubeInVolume(volData, Vector3DInt32(minPos, midPos+1, midPos+1), Vector3DInt32(midPos-1, maxPos, maxPos), 0); - createCubeInVolume(volData, Vector3DInt32(1, midPos-10, midPos-10), Vector3DInt32(maxPos-1, midPos+10, midPos+10), VoxelTypeTraits::MaxDensity); - createCubeInVolume(volData, Vector3DInt32(midPos-10, 1, midPos-10), Vector3DInt32(midPos+10, maxPos-1, midPos+10), VoxelTypeTraits::MaxDensity); - createCubeInVolume(volData, Vector3DInt32(midPos-10, midPos-10 ,1), Vector3DInt32(midPos+10, midPos+10, maxPos-1), VoxelTypeTraits::MaxDensity); + createCubeInVolume(volData, Vector3DInt32(1, midPos-10, midPos-10), Vector3DInt32(maxPos-1, midPos+10, midPos+10), VoxelTypeTraits::maxDensity()); + createCubeInVolume(volData, Vector3DInt32(midPos-10, 1, midPos-10), Vector3DInt32(midPos+10, maxPos-1, midPos+10), VoxelTypeTraits::maxDensity()); + createCubeInVolume(volData, Vector3DInt32(midPos-10, midPos-10 ,1), Vector3DInt32(midPos+10, midPos+10, maxPos-1), VoxelTypeTraits::maxDensity()); //Smooth part of the volume RawVolume tempVolume(PolyVox::Region(0,0,0,128, 128, 128)); diff --git a/examples/Paging/OpenGLWidget.cpp b/examples/Paging/OpenGLWidget.cpp index dacfe30f..4347be2f 100644 --- a/examples/Paging/OpenGLWidget.cpp +++ b/examples/Paging/OpenGLWidget.cpp @@ -132,4 +132,4 @@ void OpenGLWidget::mouseMoveEvent(QMouseEvent* event) m_LastFrameMousePos = m_CurrentMousePos; update(); -} \ No newline at end of file +} diff --git a/examples/Paging/OpenGLWidget.h b/examples/Paging/OpenGLWidget.h index 199a33ed..011b9734 100644 --- a/examples/Paging/OpenGLWidget.h +++ b/examples/Paging/OpenGLWidget.h @@ -64,4 +64,4 @@ private: int m_yRotation; }; -#endif //__BasicExample_OpenGLWidget_H__ \ No newline at end of file +#endif //__BasicExample_OpenGLWidget_H__ diff --git a/examples/Paging/main.cpp b/examples/Paging/main.cpp index c24aff55..0de7d324 100644 --- a/examples/Paging/main.cpp +++ b/examples/Paging/main.cpp @@ -50,7 +50,7 @@ void createPerlinVolumeSlow(LargeVolume& volData) perlinVal += 1.0f; perlinVal *= 0.5f; - perlinVal *= VoxelTypeTraits::MaxDensity; + perlinVal *= VoxelTypeTraits::maxDensity(); MaterialDensityPair44 voxel; @@ -60,12 +60,12 @@ void createPerlinVolumeSlow(LargeVolume& volData) /*if(perlinVal < 0.0f) { voxel.setMaterial(245); - voxel.setDensity(VoxelTypeTraits::MaxDensity); + voxel.setDensity(VoxelTypeTraits::maxDensity()); } else { voxel.setMaterial(0); - voxel.setDensity(VoxelTypeTraits::MinDensity); + voxel.setDensity(VoxelTypeTraits::minDensity()); }*/ volData.setVoxelAt(x, y, z, voxel); @@ -105,12 +105,12 @@ void createPerlinVolumeSlow(LargeVolume& volData) if(perlinVal < 0.0f) { voxel.setMaterial(245); - voxel.setDensity(VoxelTypeTraits::MaxDensity); + voxel.setDensity(VoxelTypeTraits::maxDensity()); } else { voxel.setMaterial(0); - voxel.setDensity(VoxelTypeTraits::MinDensity); + voxel.setDensity(VoxelTypeTraits::minDensity()); } volData.setVoxelAt(x, y, z, voxel); @@ -143,12 +143,12 @@ void createPerlinTerrain(LargeVolume& volData) if(z < perlinVal) { voxel.setMaterial(245); - voxel.setDensity(VoxelTypeTraits::MaxDensity); + voxel.setDensity(VoxelTypeTraits::maxDensity()); } else { voxel.setMaterial(0); - voxel.setDensity(VoxelTypeTraits::MinDensity); + voxel.setDensity(VoxelTypeTraits::minDensity()); } volData.setVoxelAt(x, y, z, voxel); @@ -181,7 +181,7 @@ void createSphereInVolume(LargeVolume& volData, Vector3DF if(fDistToCenter <= fRadius) { //Our new density value - uint8_t uDensity = VoxelTypeTraits::MaxDensity; + uint8_t uDensity = VoxelTypeTraits::maxDensity(); //Get the old voxel MaterialDensityPair44 voxel = volData.getVoxelAt(x,y,z); @@ -219,17 +219,17 @@ void load(const ConstVolumeProxy& volume, const PolyVox:: if((x-xpos)*(x-xpos) + (z-zpos)*(z-zpos) < 200) { // tunnel voxel.setMaterial(0); - voxel.setDensity(VoxelTypeTraits::MinDensity); + voxel.setDensity(VoxelTypeTraits::minDensity()); } else { // solid voxel.setMaterial(245); - voxel.setDensity(VoxelTypeTraits::MaxDensity); + voxel.setDensity(VoxelTypeTraits::maxDensity()); } } else { voxel.setMaterial(0); - voxel.setDensity(VoxelTypeTraits::MinDensity); + voxel.setDensity(VoxelTypeTraits::minDensity()); } volume.setVoxelAt(x, y, z, voxel); diff --git a/examples/SmoothLOD/OpenGLWidget.cpp b/examples/SmoothLOD/OpenGLWidget.cpp index 52aaaf65..7c706648 100644 --- a/examples/SmoothLOD/OpenGLWidget.cpp +++ b/examples/SmoothLOD/OpenGLWidget.cpp @@ -183,4 +183,4 @@ void OpenGLWidget::mouseMoveEvent(QMouseEvent* event) m_LastFrameMousePos = m_CurrentMousePos; update(); -} \ No newline at end of file +} diff --git a/examples/SmoothLOD/OpenGLWidget.h b/examples/SmoothLOD/OpenGLWidget.h index 4dc465e0..059c369e 100644 --- a/examples/SmoothLOD/OpenGLWidget.h +++ b/examples/SmoothLOD/OpenGLWidget.h @@ -71,4 +71,4 @@ private: int m_yRotation; }; -#endif //__BasicExample_OpenGLWidget_H__ \ No newline at end of file +#endif //__BasicExample_OpenGLWidget_H__ diff --git a/examples/SmoothLOD/main.cpp b/examples/SmoothLOD/main.cpp index 83bc2949..be423a76 100644 --- a/examples/SmoothLOD/main.cpp +++ b/examples/SmoothLOD/main.cpp @@ -35,7 +35,7 @@ freely, subject to the following restrictions: //Use the PolyVox namespace using namespace PolyVox; -void createSphereInVolume(SimpleVolume& volData, float fRadius) +void createSphereInVolume(SimpleVolume& volData, float fRadius) { //This vector hold the position of the center of the volume Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2); @@ -55,17 +55,17 @@ void createSphereInVolume(SimpleVolume& volData, float fRadius) if(fDistToCenter <= fRadius) { //Our new density value - //uint8_t uDensity = Density8::getMaxDensity(); - uint8_t uDensity = VoxelTypeTraits::MaxDensity; + //uint8_t uDensity = Density8::getmaxDensity()(); + uint8_t uDensity = VoxelTypeTraits::maxDensity(); //Get the old voxel - Density8 voxel = volData.getVoxelAt(x,y,z); + //uint8_t voxel = volData.getVoxelAt(x,y,z); //Modify the density - voxel.setDensity(uDensity); + //voxel.setDensity(uDensity); //Wrte the voxel value into the volume - volData.setVoxelAt(x, y, z, voxel); + volData.setVoxelAt(x, y, z, uDensity); } //144 in the middle, (144 - 32) at the edges. Threshold of 128 is between these @@ -83,7 +83,7 @@ int main(int argc, char *argv[]) openGLWidget.show(); //Create an empty volume and then place a sphere in it - SimpleVolume volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(63, 63, 63))); + SimpleVolume volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(63, 63, 63))); createSphereInVolume(volData, 28); //Smooth the data - should reimplement this using LowPassFilter @@ -91,20 +91,20 @@ int main(int argc, char *argv[]) //smoothRegion(volData, volData.getEnclosingRegion()); //smoothRegion(volData, volData.getEnclosingRegion()); - RawVolume volDataLowLOD(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(15, 31, 31))); + RawVolume volDataLowLOD(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(15, 31, 31))); - VolumeResampler volumeResampler(&volData, PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 63, 63)), &volDataLowLOD, volDataLowLOD.getEnclosingRegion()); + VolumeResampler volumeResampler(&volData, PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 63, 63)), &volDataLowLOD, volDataLowLOD.getEnclosingRegion()); volumeResampler.execute(); //Extract the surface SurfaceMesh meshLowLOD; - SurfaceExtractor surfaceExtractor(&volDataLowLOD, volDataLowLOD.getEnclosingRegion(), &meshLowLOD); + SurfaceExtractor surfaceExtractor(&volDataLowLOD, volDataLowLOD.getEnclosingRegion(), &meshLowLOD); surfaceExtractor.execute(); meshLowLOD.scaleVertices(/*2.0f*/63.0f / 31.0f); //Extract the surface SurfaceMesh meshHighLOD; - SurfaceExtractor surfaceExtractorHigh(&volData, PolyVox::Region(Vector3DInt32(30,0,0), Vector3DInt32(63, 63, 63)), &meshHighLOD); + SurfaceExtractor surfaceExtractorHigh(&volData, PolyVox::Region(Vector3DInt32(30,0,0), Vector3DInt32(63, 63, 63)), &meshHighLOD); surfaceExtractorHigh.execute(); meshHighLOD.translateVertices(Vector3DFloat(30, 0, 0)); diff --git a/library/PolyVoxCore/CMakeLists.txt b/library/PolyVoxCore/CMakeLists.txt index 5c73631e..7439a78c 100644 --- a/library/PolyVoxCore/CMakeLists.txt +++ b/library/PolyVoxCore/CMakeLists.txt @@ -9,12 +9,12 @@ SET(CORE_SRC_FILES source/Density.cpp source/GradientEstimators.cpp source/Log.cpp + source/Material.cpp source/MaterialDensityPair.cpp source/MeshDecimator.cpp source/Region.cpp source/SimpleInterface.cpp source/VertexTypes.cpp - source/Voxel.cpp source/VoxelFilters.cpp ) @@ -51,6 +51,7 @@ SET(CORE_INC_FILES include/PolyVoxCore/MeshDecimator.h include/PolyVoxCore/MeshDecimator.inl include/PolyVoxCore/PolyVoxForwardDeclarations.h + include/PolyVoxCore/PrimitiveVoxelTypes.h include/PolyVoxCore/RawVolume.h include/PolyVoxCore/RawVolume.inl include/PolyVoxCore/RawVolumeSampler.inl diff --git a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h index 572cb0f1..b7e28223 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h +++ b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h @@ -28,6 +28,7 @@ freely, subject to the following restrictions: #include "PolyVoxImpl/TypeDef.h" #include "PolyVoxCore/Array.h" +#include "PolyVoxCore/Voxel.h" #include #include //For runtime_error @@ -43,7 +44,7 @@ namespace PolyVox extern const POLYVOX_API Vector3DInt32 arrayPathfinderCorners[8]; /// This function provides the default method for checking whether a given voxel - /// is vaid for the path computed by the AStarPathfinder. + /// is valid for the path computed by the AStarPathfinder. template< template class VolumeType, typename VoxelType> bool aStarDefaultVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos); @@ -71,7 +72,7 @@ namespace PolyVox float fHBias = 1.0, uint32_t uMaxNoOfNodes = 10000, Connectivity connectivity = TwentySixConnected, - polyvox_function*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator, + polyvox_function*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator, polyvox_function funcProgressCallback = 0 ) :volume(volData) diff --git a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl index 76262eb1..764488f8 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl @@ -37,13 +37,6 @@ namespace PolyVox return false; } - //and if their density is below the threshold. - VoxelType voxel = volData->getVoxelAt(v3dPos); - if(voxel.getDensity() >= VoxelType::getThreshold()) - { - return false; - } - return true; } @@ -333,4 +326,4 @@ namespace PolyVox hVal += fHash; return hVal; } -} \ No newline at end of file +} diff --git a/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.h b/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.h index c1310c4c..cafcf6bc 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.h +++ b/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.h @@ -31,6 +31,12 @@ freely, subject to the following restrictions: #include "PolyVoxCore/Region.h" #include "PolyVoxCore/Raycast.h" +#if defined(_MSC_VER) + //These two should not be here! + #include "PolyVoxCore/Material.h" + #include "PolyVoxCore/SimpleVolume.h" +#endif + #include namespace PolyVox @@ -39,12 +45,19 @@ namespace PolyVox class AmbientOcclusionCalculator { public: - AmbientOcclusionCalculator(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement); + AmbientOcclusionCalculator(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, polyvox_function funcIsTransparent); ~AmbientOcclusionCalculator(); void execute(void); private: + +#if defined(_MSC_VER) //FIXME: To be investigated. Linux version is more general and should be correct. + bool raycastCallback(const typename SimpleVolume::Sampler& sampler); +#else + bool raycastCallback(const typename VolumeType::Sampler& sampler); +#endif + Region m_region; typename VolumeType::Sampler m_sampVolume; VolumeType* m_volInput; @@ -56,6 +69,8 @@ namespace PolyVox uint16_t mRandomUnitVectorIndex; uint16_t mRandomVectorIndex; uint16_t mIndexIncreament; + + polyvox_function m_funcIsTransparent; }; } diff --git a/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.inl b/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.inl index 29e7e4ae..a38ce720 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/AmbientOcclusionCalculator.inl @@ -24,7 +24,7 @@ freely, subject to the following restrictions: namespace PolyVox { template< template class VolumeType, typename VoxelType> - AmbientOcclusionCalculator::AmbientOcclusionCalculator(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement) + AmbientOcclusionCalculator::AmbientOcclusionCalculator(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, polyvox_function funcIsTransparent) :m_region(region) ,m_sampVolume(volInput) ,m_volInput(volInput) @@ -33,6 +33,7 @@ namespace PolyVox ,m_uNoOfSamplesPerOutputElement(uNoOfSamplesPerOutputElement) ,mRandomUnitVectorIndex(0) //Although these could be uninitialised, we ,mRandomVectorIndex(0) //initialise for consistant results in the tests. + ,m_funcIsTransparent(funcIsTransparent) { //Make sure that the size of the volume is an exact multiple of the size of the array. assert(m_volInput->getWidth() % arrayResult->getDimension(0) == 0); @@ -74,7 +75,7 @@ namespace PolyVox const Vector3DFloat v3dOffset(0.5f,0.5f,0.5f); RaycastResult raycastResult; - Raycast raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult); + Raycast raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult, polyvox_bind(&PolyVox::AmbientOcclusionCalculator::raycastCallback, this, std::placeholders::_1)); //This loop iterates over the bottom-lower-left voxel in each of the cells in the output array for(uint16_t z = m_region.getLowerCorner().getZ(); z <= m_region.getUpperCorner().getZ(); z += iRatioZ) @@ -131,4 +132,15 @@ namespace PolyVox } } } -} \ No newline at end of file + + template< template class VolumeType, typename VoxelType> +#if defined(_MSC_VER) + bool AmbientOcclusionCalculator::raycastCallback(const typename SimpleVolume::Sampler& sampler) +#else + bool AmbientOcclusionCalculator::raycastCallback(const typename VolumeType::Sampler& sampler) +#endif + { + VoxelType voxel = sampler.getVoxel(); + return m_funcIsTransparent(voxel); + } +} diff --git a/library/PolyVoxCore/include/PolyVoxCore/ArraySizes.h b/library/PolyVoxCore/include/PolyVoxCore/ArraySizes.h index 5ea88078..a8afd876 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/ArraySizes.h +++ b/library/PolyVoxCore/include/PolyVoxCore/ArraySizes.h @@ -74,4 +74,4 @@ namespace PolyVox }; }//namespace PolyVox -#endif //__PolyVox_ArraySizes_H__ \ No newline at end of file +#endif //__PolyVox_ArraySizes_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h index 46ea2567..7b016988 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h @@ -50,9 +50,7 @@ namespace PolyVox Sampler(DerivedVolumeType* volume); ~Sampler(); - int32_t getPosX(void) const; - int32_t getPosY(void) const; - int32_t getPosZ(void) const; + Vector3DInt32 getPosition(void) const; inline VoxelType getVoxel(void) const; void setPosition(const Vector3DInt32& v3dNewPos); diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl index 01fcca4a..d1a12a77 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl @@ -41,23 +41,9 @@ namespace PolyVox template template - int32_t BaseVolume::Sampler::getPosX(void) const + Vector3DInt32 BaseVolume::Sampler::getPosition(void) const { - return mXPosInVolume; - } - - template - template - int32_t BaseVolume::Sampler::getPosY(void) const - { - return mYPosInVolume; - } - - template - template - int32_t BaseVolume::Sampler::getPosZ(void) const - { - return mZPosInVolume; + return Vector3DInt32(mXPosInVolume, mYPosInVolume, mZPosInVolume); } template diff --git a/library/PolyVoxCore/include/PolyVoxCore/ConstVolumeProxy.h b/library/PolyVoxCore/include/PolyVoxCore/ConstVolumeProxy.h index 699edd43..cac2a282 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/ConstVolumeProxy.h +++ b/library/PolyVoxCore/include/PolyVoxCore/ConstVolumeProxy.h @@ -76,4 +76,4 @@ namespace PolyVox }; } -#endif //__PolyVox_ConstVolumeProxy_H__ \ No newline at end of file +#endif //__PolyVox_ConstVolumeProxy_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl index 7d8e5206..b28b0d0b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl @@ -91,10 +91,10 @@ namespace PolyVox volumeSampler.setPosition(x,y,z); VoxelType currentVoxel = volumeSampler.getVoxel(); - bool currentVoxelIsSolid = currentVoxel.getDensity() >= VoxelType::getThreshold(); + bool currentVoxelIsSolid = currentVoxel.getMaterial() != 0; VoxelType negXVoxel = volumeSampler.peekVoxel1nx0py0pz(); - bool negXVoxelIsSolid = negXVoxel.getDensity() >= VoxelType::getThreshold(); + bool negXVoxelIsSolid = negXVoxel.getMaterial() != 0; if((currentVoxelIsSolid != negXVoxelIsSolid) && (finalY == false) && (finalZ == false)) { @@ -131,7 +131,7 @@ namespace PolyVox } VoxelType negYVoxel = volumeSampler.peekVoxel0px1ny0pz(); - bool negYVoxelIsSolid = negYVoxel.getDensity() >= VoxelType::getThreshold(); + bool negYVoxelIsSolid = negYVoxel.getMaterial() != 0; if((currentVoxelIsSolid != negYVoxelIsSolid) && (finalX == false) && (finalZ == false)) { @@ -168,7 +168,7 @@ namespace PolyVox } VoxelType negZVoxel = volumeSampler.peekVoxel0px0py1nz(); - bool negZVoxelIsSolid = negZVoxel.getDensity() >= VoxelType::getThreshold(); + bool negZVoxelIsSolid = negZVoxel.getMaterial() != 0; if((currentVoxelIsSolid != negZVoxelIsSolid) && (finalX == false) && (finalY == false)) { @@ -344,4 +344,4 @@ namespace PolyVox //Quads cannot be merged. return false; } -} \ No newline at end of file +} diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.inl b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.inl index c448cbba..bf47a80b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.inl @@ -48,9 +48,9 @@ namespace PolyVox float regY = static_cast(y - m_regSizeInVoxels.getLowerCorner().getY()); float regZ = static_cast(z - m_regSizeInVoxels.getLowerCorner().getZ()); - int currentVoxel = m_volData->getVoxelAt(x,y,z).getDensity() >= VoxelType::getThreshold(); + int currentVoxel = m_volData->getVoxelAt(x,y,z).getMaterial() != 0; - int plusXVoxel = m_volData->getVoxelAt(x+1,y,z).getDensity() >= VoxelType::getThreshold(); + int plusXVoxel = m_volData->getVoxelAt(x+1,y,z).getMaterial() != 0; if(currentVoxel > plusXVoxel) { float material = static_cast(m_volData->getVoxelAt(x,y,z).getMaterial()); @@ -76,7 +76,7 @@ namespace PolyVox m_meshCurrent->addTriangleCubic(v1,v3,v2); } - int plusYVoxel = m_volData->getVoxelAt(x,y+1,z).getDensity() >= VoxelType::getThreshold(); + int plusYVoxel = m_volData->getVoxelAt(x,y+1,z).getMaterial() != 0; if(currentVoxel > plusYVoxel) { float material = static_cast(m_volData->getVoxelAt(x,y,z).getMaterial()); @@ -102,7 +102,7 @@ namespace PolyVox m_meshCurrent->addTriangleCubic(v1,v2,v3); } - int plusZVoxel = m_volData->getVoxelAt(x,y,z+1).getDensity() >= VoxelType::getThreshold(); + int plusZVoxel = m_volData->getVoxelAt(x,y,z+1).getMaterial() != 0; if(currentVoxel > plusZVoxel) { float material = static_cast(m_volData->getVoxelAt(x,y,z).getMaterial()); @@ -139,4 +139,4 @@ namespace PolyVox lodRecord.endIndex = m_meshCurrent->getNoOfIndices(); m_meshCurrent->m_vecLodRecords.push_back(lodRecord); } -} \ No newline at end of file +} diff --git a/library/PolyVoxCore/include/PolyVoxCore/Density.h b/library/PolyVoxCore/include/PolyVoxCore/Density.h index 14946f08..acce62b1 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Density.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Density.h @@ -31,6 +31,9 @@ freely, subject to the following restrictions: #include #include +#undef min +#undef max + namespace PolyVox { ///This class represents a voxel storing only a density. @@ -45,8 +48,11 @@ namespace PolyVox /// /// \sa Material, MaterialDensityPair //////////////////////////////////////////////////////////////////////////////// + + // int32_t template parameter is a dummy, required as the compiler expects to be able to declare an + // instance of VoxelType::MaterialType without knowing that VoxelType doesn't actually have a material. template - class Density : public Voxel + class Density { public: //We expose DensityType and MaterialType in this way so that, when code is @@ -54,7 +60,7 @@ namespace PolyVox //using code such as 'VoxelType::DensityType value = voxel.getDensity()' //or 'VoxelType::MaterialType value = voxel.getMaterial()'. typedef Type DensityType; - typedef uint8_t MaterialType; //Shouldn't define this one... + typedef int32_t MaterialType; //Shouldn't define this one... Density() : m_uDensity(0) {} Density(DensityType uDensity) : m_uDensity(uDensity) {} @@ -70,13 +76,13 @@ namespace PolyVox } DensityType getDensity() const throw() { return m_uDensity; } - MaterialType getMaterial() const throw() { return 1; } + //MaterialType getMaterial() const throw() { return 1; } void setDensity(DensityType uDensity) { m_uDensity = uDensity; } - void setMaterial(MaterialType /*uMaterial*/) { assert(false); } //Cannot set material on voxel of type Density + //void setMaterial(MaterialType /*uMaterial*/) { assert(false); } //Cannot set material on voxel of type Density - //static DensityType getMaxDensity() throw() { return (std::numeric_limits::max)(); } - //static DensityType getMinDensity() throw() { return (std::numeric_limits::min)(); } + //static DensityType getmaxDensity()() throw() { return (std::numeric_limits::max)(); } + //static DensityType getminDensity()() throw() { return (std::numeric_limits::min)(); } static DensityType getThreshold() throw() { return (std::numeric_limits::max)() / 2; } private: @@ -85,70 +91,20 @@ namespace PolyVox // These are the predefined density types. The 8-bit types are sufficient for many purposes (including // most games) but 16-bit and float types do have uses particularly in medical/scientific visualisation. - typedef Density DensityI8; - typedef Density DensityU8; - typedef Density DensityI16; - typedef Density DensityU16; - typedef Density DensityFloat; - typedef Density DensityDouble; - - // These types are here for backwards compatibility but they are a little ambiguous as the name doesn't indicate - // whether the values are signed. We would recommend using one of the 8 or 16 bit predefined types above instead. typedef Density Density8; - typedef Density Density16; - // We have to define all the min and max values explicitly here rather than using std::numeric_limits because we need - // compile time constants. The new 'constexpr' would help here but it's not supported by all compilers at the moment. - /*template<> - class VoxelTypeTraits< Density > + template<> + class VoxelTypeTraits< Density8 > { public: - const static int8_t MinDensity; - const static int8_t MaxDensity; - };*/ - - /*template<> - class VoxelTypeTraits< Density > - { - public: - const static uint8_t MinDensity; - const static uint8_t MaxDensity; - };*/ - - /*template<> - class VoxelTypeTraits< Density > - { - public: - const static int16_t MinDensity; - const static int16_t MaxDensity; + typedef uint8_t DensityType; + typedef uint8_t MaterialType; + static Density8::DensityType minDensity() { return std::numeric_limits::min(); } + static Density8::DensityType maxDensity() { return std::numeric_limits::max(); } }; template<> - class VoxelTypeTraits< Density > - { - public: - const static uint16_t MinDensity; - const static uint16_t MaxDensity; - }; - - //Constants for float defined in .cpp file as they are not integers. - template<> - class VoxelTypeTraits< Density > - { - public: - const static float MinDensity; - const static float MaxDensity; - }; - - //Constants for double defined in .cpp file as they are not integers. - template<> - class VoxelTypeTraits< Density > - { - public: - const static double MinDensity; - const static double MaxDensity; - };*/ - + typename VoxelTypeTraits::DensityType convertToDensity(Density8 voxel); } #endif //__PolyVox_Density_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/GradientEstimators.inl b/library/PolyVoxCore/include/PolyVoxCore/GradientEstimators.inl index eec70eca..0c92275d 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/GradientEstimators.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/GradientEstimators.inl @@ -47,9 +47,9 @@ namespace PolyVox template< template class VolumeType, typename VoxelType> Vector3DFloat computeDecimatedCentralDifferenceGradient(const typename VolumeType::Sampler& volIter) { - const int32_t x = volIter.getPosX(); - const int32_t y = volIter.getPosY(); - const int32_t z = volIter.getPosZ(); + const int32_t x = volIter.getPosition().getX(); + const int32_t y = volIter.getPosition().getY(); + const int32_t z = volIter.getPosition().getZ(); //FIXME - bitwise way of doing this? VoxelType voxel1nx = volIter.getVoxelAt(x-2, y ,z ) > 0 ? 1: 0; @@ -72,9 +72,9 @@ namespace PolyVox template< template class VolumeType, typename VoxelType> Vector3DFloat computeSmoothCentralDifferenceGradient(typename VolumeType::Sampler& volIter) { - int32_t initialX = volIter.getPosX(); - int32_t initialY = volIter.getPosY(); - int32_t initialZ = volIter.getPosZ(); + int32_t initialX = volIter.getPosition().getX(); + int32_t initialY = volIter.getPosition().getY(); + int32_t initialZ = volIter.getPosition().getZ(); //FIXME - bitwise way of doing this? volIter.setPosition(initialX-1, initialY, initialZ); @@ -189,9 +189,9 @@ namespace PolyVox static const int weights[3][3][3] = { { {2,3,2}, {3,6,3}, {2,3,2} }, { {3,6,3}, {6,0,6}, {3,6,3} }, { {2,3,2}, {3,6,3}, {2,3,2} } }; - int32_t initialX = volIter.getPosX(); - int32_t initialY = volIter.getPosY(); - int32_t initialZ = volIter.getPosZ(); + int32_t initialX = volIter.getPosition().getX(); + int32_t initialY = volIter.getPosition().getY(); + int32_t initialZ = volIter.getPosition().getZ(); volIter.setPosition(initialX-1, initialY-1, initialZ-1); const float pVoxel1nx1ny1nz = computeSmoothedVoxel(volIter); volIter.setPosition(initialX-1, initialY-1, initialZ ); const float pVoxel1nx1ny0pz = computeSmoothedVoxel(volIter); diff --git a/library/PolyVoxCore/include/PolyVoxCore/IteratorController.inl b/library/PolyVoxCore/include/PolyVoxCore/IteratorController.inl index 82fbdd08..d5aef352 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/IteratorController.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/IteratorController.inl @@ -32,7 +32,7 @@ namespace PolyVox template bool IteratorController::moveForward(void) { - Vector3DInt32 v3dInitialPosition(m_Iter->getPosX(), m_Iter->getPosY(), m_Iter->getPosZ()); + Vector3DInt32 v3dInitialPosition(m_Iter->getPosition().getX(), m_Iter->getPosition().getY(), m_Iter->getPosition().getZ()); if(v3dInitialPosition.getX() < m_regValid.getUpperCorner().getX()) { diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h index 9399f669..d6a7ecd2 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h @@ -172,9 +172,6 @@ namespace PolyVox Sampler& operator=(const Sampler& rhs) throw(); - int32_t getPosX(void) const; - int32_t getPosY(void) const; - int32_t getPosZ(void) const; VoxelType getSubSampledVoxel(uint8_t uLevel) const; inline VoxelType getVoxel(void) const; @@ -299,10 +296,9 @@ namespace PolyVox /// Calculates approximatly how many bytes of memory the volume is currently using. uint32_t calculateSizeInBytes(void); - /// Deprecated - I don't think we should expose this function? Let us know if you disagree... - void resize(const Region& regValidRegion, uint16_t uBlockSideLength); - private: + void initialise(const Region& regValidRegion, uint16_t uBlockSideLength); + /// gets called when a new region is allocated and needs to be filled /// NOTE: accessing ANY voxels outside this region during the process of this function /// is absolutely unsafe diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl index d5ae0004..9fda97f4 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl @@ -45,7 +45,7 @@ namespace PolyVox m_funcDataOverflowHandler = dataOverflowHandler; m_bPagingEnabled = true; //Create a volume of the right size. - resize(Region::MaxRegion,uBlockSideLength); + initialise(Region::MaxRegion,uBlockSideLength); } //////////////////////////////////////////////////////////////////////////////// @@ -93,7 +93,7 @@ namespace PolyVox m_bPagingEnabled = bPagingEnabled; //Create a volume of the right size. - resize(regValid,uBlockSideLength); + initialise(regValid,uBlockSideLength); } //////////////////////////////////////////////////////////////////////////////// @@ -391,7 +391,7 @@ namespace PolyVox /// This function should probably be made internal... //////////////////////////////////////////////////////////////////////////////// template - void LargeVolume::resize(const Region& regValidRegion, uint16_t uBlockSideLength) + void LargeVolume::initialise(const Region& regValidRegion, uint16_t uBlockSideLength) { //Debug mode validation assert(uBlockSideLength > 0); diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolumeSampler.inl index be063dc7..d827542b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolumeSampler.inl @@ -54,24 +54,6 @@ namespace PolyVox return *this; } - template - int32_t LargeVolume::Sampler::getPosX(void) const - { - return this->mXPosInVolume; - } - - template - int32_t LargeVolume::Sampler::getPosY(void) const - { - return this->mYPosInVolume; - } - - template - int32_t LargeVolume::Sampler::getPosZ(void) const - { - return this->mZPosInVolume; - } - template VoxelType LargeVolume::Sampler::getSubSampledVoxel(uint8_t uLevel) const { @@ -321,7 +303,7 @@ namespace PolyVox template VoxelType LargeVolume::Sampler::peekVoxel1nx1py1nz(void) const { - if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mYPosInVolume) ) + if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) ) { return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength); } @@ -530,4 +512,4 @@ namespace PolyVox } #undef BORDER_LOW -#undef BORDER_HIGH \ No newline at end of file +#undef BORDER_HIGH diff --git a/library/PolyVoxCore/include/PolyVoxCore/Log.h b/library/PolyVoxCore/include/PolyVoxCore/Log.h index d482fbf1..cf7efa8d 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Log.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Log.h @@ -60,4 +60,4 @@ namespace PolyVox #define POLYVOX_LOG_WARN(message) if(logHandler){logHandler(message, LS_WARN);} #define POLYVOX_LOG_ERROR(message) if(logHandler){logHandler(message, LS_ERROR);} -#endif \ No newline at end of file +#endif diff --git a/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl b/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl index e5c4c261..87eb2edb 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl @@ -76,35 +76,35 @@ namespace PolyVox VoxelType tSrcVoxel = srcSampler.getVoxel(); uint32_t uDensity = 0; - uDensity += srcSampler.peekVoxel1nx1ny1nz().getDensity(); - uDensity += srcSampler.peekVoxel1nx1ny0pz().getDensity(); - uDensity += srcSampler.peekVoxel1nx1ny1pz().getDensity(); - uDensity += srcSampler.peekVoxel1nx0py1nz().getDensity(); - uDensity += srcSampler.peekVoxel1nx0py0pz().getDensity(); - uDensity += srcSampler.peekVoxel1nx0py1pz().getDensity(); - uDensity += srcSampler.peekVoxel1nx1py1nz().getDensity(); - uDensity += srcSampler.peekVoxel1nx1py0pz().getDensity(); - uDensity += srcSampler.peekVoxel1nx1py1pz().getDensity(); + uDensity += convertToDensity(srcSampler.peekVoxel1nx1ny1nz()); + uDensity += convertToDensity(srcSampler.peekVoxel1nx1ny0pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1nx1ny1pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1nx0py1nz()); + uDensity += convertToDensity(srcSampler.peekVoxel1nx0py0pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1nx0py1pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1nx1py1nz()); + uDensity += convertToDensity(srcSampler.peekVoxel1nx1py0pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1nx1py1pz()); - uDensity += srcSampler.peekVoxel0px1ny1nz().getDensity(); - uDensity += srcSampler.peekVoxel0px1ny0pz().getDensity(); - uDensity += srcSampler.peekVoxel0px1ny1pz().getDensity(); - uDensity += srcSampler.peekVoxel0px0py1nz().getDensity(); - uDensity += srcSampler.peekVoxel0px0py0pz().getDensity(); - uDensity += srcSampler.peekVoxel0px0py1pz().getDensity(); - uDensity += srcSampler.peekVoxel0px1py1nz().getDensity(); - uDensity += srcSampler.peekVoxel0px1py0pz().getDensity(); - uDensity += srcSampler.peekVoxel0px1py1pz().getDensity(); + uDensity += convertToDensity(srcSampler.peekVoxel0px1ny1nz()); + uDensity += convertToDensity(srcSampler.peekVoxel0px1ny0pz()); + uDensity += convertToDensity(srcSampler.peekVoxel0px1ny1pz()); + uDensity += convertToDensity(srcSampler.peekVoxel0px0py1nz()); + uDensity += convertToDensity(srcSampler.peekVoxel0px0py0pz()); + uDensity += convertToDensity(srcSampler.peekVoxel0px0py1pz()); + uDensity += convertToDensity(srcSampler.peekVoxel0px1py1nz()); + uDensity += convertToDensity(srcSampler.peekVoxel0px1py0pz()); + uDensity += convertToDensity(srcSampler.peekVoxel0px1py1pz()); - uDensity += srcSampler.peekVoxel1px1ny1nz().getDensity(); - uDensity += srcSampler.peekVoxel1px1ny0pz().getDensity(); - uDensity += srcSampler.peekVoxel1px1ny1pz().getDensity(); - uDensity += srcSampler.peekVoxel1px0py1nz().getDensity(); - uDensity += srcSampler.peekVoxel1px0py0pz().getDensity(); - uDensity += srcSampler.peekVoxel1px0py1pz().getDensity(); - uDensity += srcSampler.peekVoxel1px1py1nz().getDensity(); - uDensity += srcSampler.peekVoxel1px1py0pz().getDensity(); - uDensity += srcSampler.peekVoxel1px1py1pz().getDensity(); + uDensity += convertToDensity(srcSampler.peekVoxel1px1ny1nz()); + uDensity += convertToDensity(srcSampler.peekVoxel1px1ny0pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1px1ny1pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1px0py1nz()); + uDensity += convertToDensity(srcSampler.peekVoxel1px0py0pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1px0py1pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1px1py1nz()); + uDensity += convertToDensity(srcSampler.peekVoxel1px1py0pz()); + uDensity += convertToDensity(srcSampler.peekVoxel1px1py1pz()); uDensity /= 27; diff --git a/library/PolyVoxCore/include/PolyVoxCore/Material.h b/library/PolyVoxCore/include/PolyVoxCore/Material.h index ec91c9c0..30e47f09 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Material.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Material.h @@ -45,15 +45,18 @@ namespace PolyVox /// /// \sa Density, MaterialDensityPair //////////////////////////////////////////////////////////////////////////////// + + // int32_t template parameter is a dummy, required as the compiler expects to be able to declare an + // instance of VoxelType::DensityType without knowing that VoxelType doesn't actually have a density. template - class Material : public Voxel + class Material { public: //We expose DensityType and MaterialType in this way so that, when code is //templatised on voxel type, it can determine the underlying storage type //using code such as 'VoxelType::DensityType value = voxel.getDensity()' //or 'VoxelType::MaterialType value = voxel.getMaterial()'. - typedef uint8_t DensityType; //Shouldn't define this one... + typedef int32_t DensityType; typedef Type MaterialType; Material() : m_uMaterial(0) {} @@ -74,12 +77,12 @@ namespace PolyVox //We don't actually have a density, so make one up based on the material. if(m_uMaterial == 0) { - //return getMinDensity(); + //return getminDensity()(); return 0; } else { - //return getMaxDensity(); + //return getmaxDensity()(); return 2; } } @@ -89,8 +92,8 @@ namespace PolyVox void setDensity(DensityType /*uDensity*/) { assert(false); } //Cannot set density on voxel of type Material void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; } - //static DensityType getMaxDensity() throw() { return 2; } - //static DensityType getMinDensity() throw() { return 0; } + //static DensityType getmaxDensity()() throw() { return 2; } + //static DensityType getminDensity()() throw() { return 0; } static DensityType getThreshold() throw() { return 1; } private: @@ -99,7 +102,25 @@ namespace PolyVox typedef Material Material8; typedef Material Material16; - typedef Material Material32; + + template<> + class VoxelTypeTraits< Material8 > + { + public: + typedef uint8_t DensityType; + typedef uint8_t MaterialType; + static int minDensity() { assert(false); return 0; } + static int maxDensity() { assert(false); return 0; } + }; + + template<> + class VoxelTypeTraits< Material16 > + { + public: + typedef uint8_t DensityType; + static int minDensity() { assert(false); return 0; } + static int maxDensity() { assert(false); return 0; } + }; } #endif //__PolyVox_Material_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h index 6de6fad7..93a5c8a3 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h @@ -30,7 +30,7 @@ freely, subject to the following restrictions: namespace PolyVox { - ///This class represents a voxel storing only a density. + /// This class represents a voxel storing only a density. //////////////////////////////////////////////////////////////////////////////// /// In order to perform a surface extraction on a LargeVolume, PolyVox needs the underlying /// voxel type to provide both getDensity() and getMaterial() functions. The getDensity() @@ -45,7 +45,7 @@ namespace PolyVox /// \sa Density, Material //////////////////////////////////////////////////////////////////////////////// template - class MaterialDensityPair : public Voxel + class MaterialDensityPair { public: //We expose DensityType and MaterialType in this way so that, when code is @@ -74,8 +74,8 @@ namespace PolyVox void setDensity(DensityType uDensity) { m_uDensity = uDensity; } void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; } - //static DensityType getMaxDensity() throw() { return (0x01 << NoOfDensityBits) - 1; } - //static DensityType getMinDensity() throw() { return 0; } + //static DensityType getmaxDensity()() throw() { return (0x01 << NoOfDensityBits) - 1; } + //static DensityType getminDensity()() throw() { return 0; } static DensityType getThreshold() throw() {return 0x01 << (NoOfDensityBits - 1);} private: @@ -86,13 +86,42 @@ namespace PolyVox typedef MaterialDensityPair MaterialDensityPair44; typedef MaterialDensityPair MaterialDensityPair88; - /*template - class VoxelTypeTraits< MaterialDensityPair > + template<> + class VoxelTypeTraits< MaterialDensityPair44 > { public: - const static Type MinDensity = 0; - const static Type MaxDensity = (0x01 << NoOfDensityBits) - 1; - };*/ + typedef uint8_t DensityType; + typedef uint8_t MaterialType; + static MaterialDensityPair44::DensityType minDensity() { return 0; } + static MaterialDensityPair44::DensityType maxDensity() { return 15; } + }; + + template<> + class VoxelTypeTraits< MaterialDensityPair88 > + { + public: + typedef uint8_t DensityType; + typedef uint8_t MaterialType; + static MaterialDensityPair88::DensityType minDensity() { return 0; } + static MaterialDensityPair88::DensityType maxDensity() { return 255; } + }; } -#endif \ No newline at end of file +#include "PolyVoxCore/SurfaceExtractor.h" + +namespace PolyVox +{ + template<> + typename VoxelTypeTraits::DensityType convertToDensity(MaterialDensityPair44 voxel); + + template<> + typename VoxelTypeTraits::DensityType convertToDensity(MaterialDensityPair88 voxel); + + template<> + typename VoxelTypeTraits::MaterialType convertToMaterial(MaterialDensityPair44 voxel); + + template<> + typename VoxelTypeTraits::MaterialType convertToMaterial(MaterialDensityPair88 voxel); +} + +#endif diff --git a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h index 83b9b4df..8bca21ff 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h +++ b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h @@ -28,10 +28,13 @@ freely, subject to the following restrictions: namespace PolyVox { - //---------- Array ---------- + //////////////////////////////////////////////////////////////////////////////// + // Array + //////////////////////////////////////////////////////////////////////////////// template class Array; + typedef Array<1,float> Array1DFloat; - typedef Array<1,double> Array1DDouble; + typedef Array<1,double> Array1DDouble; typedef Array<1,int8_t> Array1DInt8; typedef Array<1,uint8_t> Array1DUint8; typedef Array<1,int16_t> Array1DInt16; @@ -40,7 +43,7 @@ namespace PolyVox typedef Array<1,uint32_t> Array1DUint32; typedef Array<2,float> Array2DFloat; - typedef Array<2,double> Array2DDouble; + typedef Array<2,double> Array2DDouble; typedef Array<2,int8_t> Array2DInt8; typedef Array<2,uint8_t> Array2DUint8; typedef Array<2,int16_t> Array2DInt16; @@ -49,51 +52,102 @@ namespace PolyVox typedef Array<2,uint32_t> Array2DUint32; typedef Array<3,float> Array3DFloat; - typedef Array<3,double> Array3DDouble; + 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; - //--------------------------------- - template class Block; - - //---------- LargeVolume ---------- - template class LargeVolume; - //--------------------------------- - - - template class Density; - typedef Density Density8; - template class Material; - typedef Material Material8; - typedef Material Material16; - typedef Material Material32; - template class MaterialDensityPair; - typedef MaterialDensityPair MaterialDensityPair44; - - template class SurfaceMesh; - class Region; - class PositionMaterial; - class PositionMaterialNormal; + //////////////////////////////////////////////////////////////////////////////// + // CubicSurfaceExtractor + //////////////////////////////////////////////////////////////////////////////// template< template class VolumeType, typename VoxelType> class CubicSurfaceExtractor; + + //////////////////////////////////////////////////////////////////////////////// + // Density + //////////////////////////////////////////////////////////////////////////////// + template class Density; + + typedef Density DensityI8; + typedef Density DensityU8; + typedef Density DensityI16; + typedef Density DensityU16; + typedef Density DensityFloat; + typedef Density DensityDouble; + + typedef DensityU8 Density8; //Backwards compatibility + typedef DensityU16 Density16; //Backwards compatibility + + //////////////////////////////////////////////////////////////////////////////// + // LargeVolume + //////////////////////////////////////////////////////////////////////////////// + template class LargeVolume; + + //////////////////////////////////////////////////////////////////////////////// + // Material + //////////////////////////////////////////////////////////////////////////////// + template class Material; + + typedef Material MaterialU8; + typedef Material MaterialU16; + typedef Material MaterialU32; + + typedef MaterialU8 Material8; + typedef MaterialU16 Material16; + typedef MaterialU32 Material32; + + //////////////////////////////////////////////////////////////////////////////// + // MaterialDensityPair + //////////////////////////////////////////////////////////////////////////////// + template class MaterialDensityPair; + + typedef MaterialDensityPair MaterialDensityPair44; + typedef MaterialDensityPair MaterialDensityPair88; + + //////////////////////////////////////////////////////////////////////////////// + // PositionMaterial + //////////////////////////////////////////////////////////////////////////////// + class PositionMaterial; + + //////////////////////////////////////////////////////////////////////////////// + // PositionMaterialNormal + //////////////////////////////////////////////////////////////////////////////// + class PositionMaterialNormal; + + //////////////////////////////////////////////////////////////////////////////// + // RawVolume + //////////////////////////////////////////////////////////////////////////////// + template class RawVolume; + + //////////////////////////////////////////////////////////////////////////////// + // Region + //////////////////////////////////////////////////////////////////////////////// + class Region; + + //////////////////////////////////////////////////////////////////////////////// + // SurfaceExtractor + //////////////////////////////////////////////////////////////////////////////// template< template class VolumeType, typename VoxelType> class SurfaceExtractor; - //---------- Vector ---------- + //////////////////////////////////////////////////////////////////////////////// + // SurfaceMesh + //////////////////////////////////////////////////////////////////////////////// + template class SurfaceMesh; + + //////////////////////////////////////////////////////////////////////////////// + // Vector + //////////////////////////////////////////////////////////////////////////////// template class Vector; typedef Vector<3,float> Vector3DFloat; - typedef Vector<3,double> Vector3DDouble; + typedef Vector<3,double> Vector3DDouble; typedef Vector<3,int8_t> Vector3DInt8; typedef Vector<3,uint8_t> Vector3DUint8; typedef Vector<3,int16_t> Vector3DInt16; typedef Vector<3,uint16_t> Vector3DUint16; typedef Vector<3,int32_t> Vector3DInt32; typedef Vector<3,uint32_t> Vector3DUint32; - //---------------------------- - - //template class Sampler; } #endif diff --git a/library/PolyVoxCore/source/Voxel.cpp b/library/PolyVoxCore/include/PolyVoxCore/PrimitiveVoxelTypes.h similarity index 84% rename from library/PolyVoxCore/source/Voxel.cpp rename to library/PolyVoxCore/include/PolyVoxCore/PrimitiveVoxelTypes.h index 2940e34d..bf1552ca 100644 --- a/library/PolyVoxCore/source/Voxel.cpp +++ b/library/PolyVoxCore/include/PolyVoxCore/PrimitiveVoxelTypes.h @@ -21,12 +21,14 @@ freely, subject to the following restrictions: distribution. *******************************************************************************/ +#ifndef __PolyVox_PrimitiveVoxelTypes_H__ +#define __PolyVox_PrimitiveVoxelTypes_H__ + #include "PolyVoxCore/Voxel.h" namespace PolyVox -{ - template - const typename Type::DensityType VoxelTypeTraits::MinDensity = 0; - template - const typename Type::DensityType VoxelTypeTraits::MaxDensity = 0; -} \ No newline at end of file +{ + +} + +#endif //__PolyVox_PrimitiveVoxelTypes_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h index 3bef1a8a..dd799ea4 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h @@ -59,9 +59,6 @@ namespace PolyVox Sampler(RawVolume* volume); ~Sampler(); - int32_t getPosX(void) const; - int32_t getPosY(void) const; - int32_t getPosZ(void) const; inline VoxelType getVoxel(void) const; void setPosition(const Vector3DInt32& v3dNewPos); @@ -144,10 +141,9 @@ namespace PolyVox /// Calculates approximatly how many bytes of memory the volume is currently using. uint32_t calculateSizeInBytes(void); - /// Deprecated - I don't think we should expose this function? Let us know if you disagree... - void resize(const Region& regValidRegion); +private: + void initialise(const Region& regValidRegion); -private: //The block data VoxelType* m_pData; diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl index c46cba6b..b6fe2220 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl @@ -37,7 +37,7 @@ namespace PolyVox setBorderValue(VoxelType()); //Create a volume of the right size. - resize(regValid); + initialise(regValid); } //////////////////////////////////////////////////////////////////////////////// @@ -157,7 +157,7 @@ namespace PolyVox /// This function should probably be made internal... //////////////////////////////////////////////////////////////////////////////// template - void RawVolume::resize(const Region& regValidRegion) + void RawVolume::initialise(const Region& regValidRegion) { this->m_regValidRegion = regValidRegion; diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl index aede84fc..758e578d 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl @@ -45,24 +45,6 @@ namespace PolyVox { } - template - int32_t RawVolume::Sampler::getPosX(void) const - { - return this->mXPosInVolume; - } - - template - int32_t RawVolume::Sampler::getPosY(void) const - { - return this->mYPosInVolume; - } - - template - int32_t RawVolume::Sampler::getPosZ(void) const - { - return this->mZPosInVolume; - } - template VoxelType RawVolume::Sampler::getVoxel(void) const { @@ -224,7 +206,7 @@ namespace PolyVox template VoxelType RawVolume::Sampler::peekVoxel1nx1py1nz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mYPosInVolume) ) + if( BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); } @@ -437,4 +419,4 @@ namespace PolyVox #undef BORDER_LOWY #undef BORDER_HIGHY #undef BORDER_LOWZ -#undef BORDER_HIGHZ \ No newline at end of file +#undef BORDER_HIGHZ diff --git a/library/PolyVoxCore/include/PolyVoxCore/Raycast.h b/library/PolyVoxCore/include/PolyVoxCore/Raycast.h index 860f4efb..cb559ec2 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Raycast.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Raycast.h @@ -59,6 +59,14 @@ namespace PolyVox /// of the RaycastResult structure and the intersectionFound flag is set to true, otherwise /// the intersectionFound flag is set to false. /// + /// Important Note: These has been confusion in the past with people not realising + /// that the length of the direction vector is important. Most graphics API can provide + /// a camera position and view direction for picking purposes, but the view direction is + /// usually normalised (i.e. of length one). If you use this view direction directly you + /// will only iterate over a single voxel and won't find what you are looking for. Instead + /// you must scale the direction vector so that it's length represents the maximum distance + /// over which you want the ray to be cast. + /// /// The following code snippet shows how the class is used: /// \code /// Vector3DFloat start(rayOrigin.x(), rayOrigin.y(), rayOrigin.z()); @@ -88,12 +96,12 @@ namespace PolyVox { public: ///Constructor - Raycast(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result); + Raycast(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, RaycastResult& result, polyvox_function::Sampler& sampler)> funcIsPassable); ///Sets the start position for the ray. void setStart(const Vector3DFloat& v3dStart); ///Set the direction for the ray. - void setDirection(const Vector3DFloat& v3dDirection); + void setDirection(const Vector3DFloat& v3dDirectionAndLength); ///Performs the raycast. void execute(); @@ -101,17 +109,19 @@ namespace PolyVox private: RaycastResult& m_result; + polyvox_function::Sampler& position)> m_funcIsPassable; + void doRaycast(float x1, float y1, float z1, float x2, float y2, float z2); VolumeType* m_volData; typename VolumeType::Sampler m_sampVolume; Vector3DFloat m_v3dStart; - Vector3DFloat m_v3dDirection; + Vector3DFloat m_v3dDirectionAndLength; float m_fMaxDistance; }; } #include "PolyVoxCore/Raycast.inl" -#endif //__PolyVox_Raycast_H__ \ No newline at end of file +#endif //__PolyVox_Raycast_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/Raycast.inl b/library/PolyVoxCore/include/PolyVoxCore/Raycast.inl index 38e84e46..a2e12668 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Raycast.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/Raycast.inl @@ -27,17 +27,18 @@ namespace PolyVox /// Builds a Raycast object. /// \param volData A pointer to the volume through which the ray will be cast. /// \param v3dStart The starting position of the ray. - /// \param v3dDirection The direction of the ray. The length of this vector also + /// \param v3dDirectionAndLength The direction of the ray. The length of this vector also /// represents the length of the ray. /// \param result An instance of RaycastResult in which the result will be stored. //////////////////////////////////////////////////////////////////////////////// template< template class VolumeType, typename VoxelType> - Raycast::Raycast(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result) + Raycast::Raycast(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, RaycastResult& result, polyvox_function::Sampler& sampler)> funcIsPassable) :m_result(result) ,m_volData(volData) ,m_sampVolume(volData) ,m_v3dStart(v3dStart) - ,m_v3dDirection(v3dDirection) + ,m_v3dDirectionAndLength(v3dDirectionAndLength) + ,m_funcIsPassable(funcIsPassable) { } @@ -51,13 +52,14 @@ namespace PolyVox } //////////////////////////////////////////////////////////////////////////////// - /// \param v3dDirection The direction of the ray. The length of this vector also + /// \param v3dDirectionAndLength The direction of the ray. The length of this vector also /// represents the length of the ray. //////////////////////////////////////////////////////////////////////////////// template< template class VolumeType, typename VoxelType> - void Raycast::setDirection(const Vector3DFloat& v3dDirection) + void Raycast::setDirection(const Vector3DFloat& v3dDirectionAndLength) { - m_v3dDirection = v3dDirection; + //FIXME: We should add a warning when the ray direction is of length one, as this seems to be a common mistake. + m_v3dDirectionAndLength = v3dDirectionAndLength; } //////////////////////////////////////////////////////////////////////////////// @@ -72,7 +74,7 @@ namespace PolyVox Vector3DFloat v3dStart = m_v3dStart + Vector3DFloat(0.5f, 0.5f, 0.5f); //Compute the end point - Vector3DFloat v3dEnd = v3dStart + m_v3dDirection; + Vector3DFloat v3dEnd = v3dStart + m_v3dDirectionAndLength; //Do the raycast doRaycast(v3dStart.getX(), v3dStart.getY(), v3dStart.getZ(), v3dEnd.getX(), v3dEnd.getY(), v3dEnd.getZ()); @@ -138,7 +140,7 @@ namespace PolyVox for(;;) { - if(m_sampVolume.getVoxel().getDensity() > VoxelType::getThreshold()) + if(!m_funcIsPassable(m_sampVolume)) { m_result.foundIntersection = true; m_result.intersectionVoxel = Vector3DInt32(i,j,k); @@ -178,4 +180,4 @@ namespace PolyVox m_result.intersectionVoxel = Vector3DInt32(0,0,0); m_result.previousVoxel = Vector3DInt32(0,0,0); } -} \ No newline at end of file +} diff --git a/library/PolyVoxCore/include/PolyVoxCore/RaycastWithCallback.h b/library/PolyVoxCore/include/PolyVoxCore/RaycastWithCallback.h index bb53812f..972d0a4f 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RaycastWithCallback.h +++ b/library/PolyVoxCore/include/PolyVoxCore/RaycastWithCallback.h @@ -33,12 +33,12 @@ namespace PolyVox { public: ///Constructor - RaycastWithCallback(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function funcCallback); + RaycastWithCallback(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, polyvox_function funcCallback); ///Sets the start position for the ray. void setStart(const Vector3DFloat& v3dStart); ///Set the direction for the ray. - void setDirection(const Vector3DFloat& v3dDirection); + void setDirection(const Vector3DFloat& v3dDirectionAndLength); ///Performs the raycast. void execute(); @@ -52,7 +52,7 @@ namespace PolyVox typename VolumeType::Sampler m_sampVolume; Vector3DFloat m_v3dStart; - Vector3DFloat m_v3dDirection; + Vector3DFloat m_v3dDirectionAndLength; float m_fMaxDistance; }; } diff --git a/library/PolyVoxCore/include/PolyVoxCore/RaycastWithCallback.inl b/library/PolyVoxCore/include/PolyVoxCore/RaycastWithCallback.inl index 2cd269e3..c3da4620 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RaycastWithCallback.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RaycastWithCallback.inl @@ -24,11 +24,11 @@ freely, subject to the following restrictions: namespace PolyVox { template< template class VolumeType, typename VoxelType> - RaycastWithCallback::RaycastWithCallback(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function funcCallback) + RaycastWithCallback::RaycastWithCallback(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, polyvox_function funcCallback) :m_volData(volData) ,m_sampVolume(volData) ,m_v3dStart(v3dStart) - ,m_v3dDirection(v3dDirection) + ,m_v3dDirectionAndLength(v3dDirectionAndLength) ,m_funcCallback(funcCallback) { //Check the user provided a callback, because it @@ -43,9 +43,9 @@ namespace PolyVox } template< template class VolumeType, typename VoxelType> - void RaycastWithCallback::setDirection(const Vector3DFloat& v3dDirection) + void RaycastWithCallback::setDirection(const Vector3DFloat& v3dDirectionAndLength) { - m_v3dDirection = v3dDirection; + m_v3dDirectionAndLength = v3dDirectionAndLength; } template< template class VolumeType, typename VoxelType> @@ -57,7 +57,7 @@ namespace PolyVox Vector3DFloat v3dStart = m_v3dStart + Vector3DFloat(0.5f, 0.5f, 0.5f); //Compute the end point - Vector3DFloat v3dEnd = v3dStart + m_v3dDirection; + Vector3DFloat v3dEnd = v3dStart + m_v3dDirectionAndLength; //Do the raycast doRaycast(v3dStart.getX(), v3dStart.getY(), v3dStart.getZ(), v3dEnd.getX(), v3dEnd.getY(), v3dEnd.getZ()); diff --git a/library/PolyVoxCore/include/PolyVoxCore/Region.h b/library/PolyVoxCore/include/PolyVoxCore/Region.h index 5c91390c..4d2f3c2b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Region.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Region.h @@ -72,6 +72,7 @@ namespace PolyVox void shift(const Vector3DInt32& amount); void shiftLowerCorner(const Vector3DInt32& amount); void shiftUpperCorner(const Vector3DInt32& amount); + //FIXME - Add dilate and erode functions? /// Deprecated and misleading Vector3DInt32 dimensions(void); /// Deprecated and misleading diff --git a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.h b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.h index 447f0f18..f6c4c48c 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.h @@ -87,9 +87,6 @@ namespace PolyVox Sampler& operator=(const Sampler& rhs) throw(); - int32_t getPosX(void) const; - int32_t getPosY(void) const; - int32_t getPosZ(void) const; VoxelType getSubSampledVoxel(uint8_t uLevel) const; inline VoxelType getVoxel(void) const; @@ -173,10 +170,9 @@ namespace PolyVox /// Calculates approximatly how many bytes of memory the volume is currently using. uint32_t calculateSizeInBytes(void); - /// Deprecated - I don't think we should expose this function? Let us know if you disagree... - void resize(const Region& regValidRegion, uint16_t uBlockSideLength); - private: + void initialise(const Region& regValidRegion, uint16_t uBlockSideLength); + Block* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; //The block data diff --git a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl index 536fe065..ef274d31 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl @@ -57,7 +57,7 @@ namespace PolyVox :BaseVolume(regValid) { //Create a volume of the right size. - resize(regValid,uBlockSideLength); + initialise(regValid,uBlockSideLength); } //////////////////////////////////////////////////////////////////////////////// @@ -174,7 +174,7 @@ namespace PolyVox /// This function should probably be made internal... //////////////////////////////////////////////////////////////////////////////// template - void SimpleVolume::resize(const Region& regValidRegion, uint16_t uBlockSideLength) + void SimpleVolume::initialise(const Region& regValidRegion, uint16_t uBlockSideLength) { //Debug mode validation assert(uBlockSideLength >= 8); diff --git a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolumeSampler.inl index 091a18a8..987912d2 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolumeSampler.inl @@ -54,24 +54,6 @@ namespace PolyVox return *this; } - template - int32_t SimpleVolume::Sampler::getPosX(void) const - { - return this->mXPosInVolume; - } - - template - int32_t SimpleVolume::Sampler::getPosY(void) const - { - return this->mYPosInVolume; - } - - template - int32_t SimpleVolume::Sampler::getPosZ(void) const - { - return this->mZPosInVolume; - } - template VoxelType SimpleVolume::Sampler::getSubSampledVoxel(uint8_t uLevel) const { @@ -329,7 +311,7 @@ namespace PolyVox template VoxelType SimpleVolume::Sampler::peekVoxel1nx1py1nz(void) const { - if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mYPosInVolume) ) + if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) ) { return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength); } diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceEdge.h b/library/PolyVoxCore/include/PolyVoxCore/SurfaceEdge.h deleted file mode 100644 index 5f516190..00000000 --- a/library/PolyVoxCore/include/PolyVoxCore/SurfaceEdge.h +++ /dev/null @@ -1,69 +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_SurfaceEdge_H__ -#define __PolyVox_SurfaceEdge_H__ - -#include "SurfaceTypes.h" - -namespace PolyVox -{ - class SurfaceEdge - { - public: - SurfaceEdge(const SurfaceVertexIterator& targetToSet,const SurfaceVertexIterator& sourceToSet); - - friend bool operator == (const SurfaceEdge& lhs, const SurfaceEdge& rhs); - friend bool operator < (const SurfaceEdge& lhs, const SurfaceEdge& rhs); - - - std::string tostring(void); - - bool isDegenerate(void); - - const SurfaceVertexIterator& getTarget(void) const; - const SurfaceVertexIterator& getSource(void) const; - const SurfaceEdgeIterator& getOtherHalfEdge(void) const; - const SurfaceEdgeIterator& getPreviousHalfEdge(void) const; - const SurfaceEdgeIterator& getNextHalfEdge(void) const; - const SurfaceTriangleIterator& getTriangle(void) const; - - void setPreviousHalfEdge(const SurfaceEdgeIterator& previousHalfEdgeToSet); - void setNextHalfEdge(const SurfaceEdgeIterator& nextHalfEdgeToSet); - void setTriangle(const SurfaceTriangleIterator& triangleToSet); - - void pairWithOtherHalfEdge(const SurfaceEdgeIterator& otherHalfEdgeToPair); - - private: - SurfaceVertexIterator target; - SurfaceVertexIterator source; - - SurfaceEdgeIterator previousHalfEdge; - SurfaceEdgeIterator nextHalfEdge; - SurfaceEdgeIterator otherHalfEdge; - - SurfaceTriangleIterator triangle; - }; -} - -#endif diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h index f634dcb5..ceddf628 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h @@ -32,11 +32,27 @@ freely, subject to the following restrictions: namespace PolyVox { + template<> + class VoxelTypeTraits< uint8_t > + { + public: + typedef uint8_t DensityType; + typedef uint8_t MaterialType; + static uint8_t minDensity() { return 0; } + static uint8_t maxDensity() { return 255; } + }; + + template + typename VoxelTypeTraits::MaterialType convertToMaterial(VoxelType voxel) + { + return 1; + } + template< template class VolumeType, typename VoxelType> class SurfaceExtractor { public: - SurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh* result); + SurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh* result, typename VoxelTypeTraits::DensityType tThreshold = (VoxelTypeTraits::minDensity() + VoxelTypeTraits::maxDensity()) / 2); void execute(); @@ -64,14 +80,14 @@ namespace PolyVox //FIXME - Should actually use DensityType here, both in principle and because the maths may be //faster (and to reduce casts). So it would be good to add a way to get DensityType from a voxel. //But watch out for when the DensityType is unsigned and the difference could be negative. - float voxel1nx = static_cast(volIter.peekVoxel1nx0py0pz().getDensity()); - float voxel1px = static_cast(volIter.peekVoxel1px0py0pz().getDensity()); + float voxel1nx = static_cast(convertToDensity(volIter.peekVoxel1nx0py0pz())); + float voxel1px = static_cast(convertToDensity(volIter.peekVoxel1px0py0pz())); - float voxel1ny = static_cast(volIter.peekVoxel0px1ny0pz().getDensity()); - float voxel1py = static_cast(volIter.peekVoxel0px1py0pz().getDensity()); + float voxel1ny = static_cast(convertToDensity(volIter.peekVoxel0px1ny0pz())); + float voxel1py = static_cast(convertToDensity(volIter.peekVoxel0px1py0pz())); - float voxel1nz = static_cast(volIter.peekVoxel0px0py1nz().getDensity()); - float voxel1pz = static_cast(volIter.peekVoxel0px0py1pz().getDensity()); + float voxel1nz = static_cast(convertToDensity(volIter.peekVoxel0px0py1nz())); + float voxel1pz = static_cast(convertToDensity(volIter.peekVoxel0px0py1pz())); return Vector3DFloat ( @@ -89,35 +105,35 @@ namespace PolyVox //FIXME - Should actually use DensityType here, both in principle and because the maths may be //faster (and to reduce casts). So it would be good to add a way to get DensityType from a voxel. //But watch out for when the DensityType is unsigned and the difference could be negative. - const float pVoxel1nx1ny1nz = static_cast(volIter.peekVoxel1nx1ny1nz().getDensity()); - const float pVoxel1nx1ny0pz = static_cast(volIter.peekVoxel1nx1ny0pz().getDensity()); - const float pVoxel1nx1ny1pz = static_cast(volIter.peekVoxel1nx1ny1pz().getDensity()); - const float pVoxel1nx0py1nz = static_cast(volIter.peekVoxel1nx0py1nz().getDensity()); - const float pVoxel1nx0py0pz = static_cast(volIter.peekVoxel1nx0py0pz().getDensity()); - const float pVoxel1nx0py1pz = static_cast(volIter.peekVoxel1nx0py1pz().getDensity()); - const float pVoxel1nx1py1nz = static_cast(volIter.peekVoxel1nx1py1nz().getDensity()); - const float pVoxel1nx1py0pz = static_cast(volIter.peekVoxel1nx1py0pz().getDensity()); - const float pVoxel1nx1py1pz = static_cast(volIter.peekVoxel1nx1py1pz().getDensity()); + const float pVoxel1nx1ny1nz = static_cast(convertToDnsity(volIter.peekVoxel1nx1ny1nz())); + const float pVoxel1nx1ny0pz = static_cast(convertToDnsity(volIter.peekVoxel1nx1ny0pz())); + const float pVoxel1nx1ny1pz = static_cast(convertToDnsity(volIter.peekVoxel1nx1ny1pz())); + const float pVoxel1nx0py1nz = static_cast(convertToDnsity(volIter.peekVoxel1nx0py1nz())); + const float pVoxel1nx0py0pz = static_cast(convertToDnsity(volIter.peekVoxel1nx0py0pz())); + const float pVoxel1nx0py1pz = static_cast(convertToDnsity(volIter.peekVoxel1nx0py1pz())); + const float pVoxel1nx1py1nz = static_cast(convertToDnsity(volIter.peekVoxel1nx1py1nz())); + const float pVoxel1nx1py0pz = static_cast(convertToDnsity(volIter.peekVoxel1nx1py0pz())); + const float pVoxel1nx1py1pz = static_cast(convertToDnsity(volIter.peekVoxel1nx1py1pz())); - const float pVoxel0px1ny1nz = static_cast(volIter.peekVoxel0px1ny1nz().getDensity()); - const float pVoxel0px1ny0pz = static_cast(volIter.peekVoxel0px1ny0pz().getDensity()); - const float pVoxel0px1ny1pz = static_cast(volIter.peekVoxel0px1ny1pz().getDensity()); - const float pVoxel0px0py1nz = static_cast(volIter.peekVoxel0px0py1nz().getDensity()); - //const float pVoxel0px0py0pz = static_cast(volIter.peekVoxel0px0py0pz().getDensity()); - const float pVoxel0px0py1pz = static_cast(volIter.peekVoxel0px0py1pz().getDensity()); - const float pVoxel0px1py1nz = static_cast(volIter.peekVoxel0px1py1nz().getDensity()); - const float pVoxel0px1py0pz = static_cast(volIter.peekVoxel0px1py0pz().getDensity()); - const float pVoxel0px1py1pz = static_cast(volIter.peekVoxel0px1py1pz().getDensity()); + const float pVoxel0px1ny1nz = static_cast(convertToDnsity(volIter.peekVoxel0px1ny1nz())); + const float pVoxel0px1ny0pz = static_cast(convertToDnsity(volIter.peekVoxel0px1ny0pz())); + const float pVoxel0px1ny1pz = static_cast(convertToDnsity(volIter.peekVoxel0px1ny1pz())); + const float pVoxel0px0py1nz = static_cast(convertToDnsity(volIter.peekVoxel0px0py1nz())); + //const float pVoxel0px0py0pz = static_cast(convertToDnsity(volIter.peekVoxel0px0py0pz())); + const float pVoxel0px0py1pz = static_cast(convertToDnsity(volIter.peekVoxel0px0py1pz())); + const float pVoxel0px1py1nz = static_cast(convertToDnsity(volIter.peekVoxel0px1py1nz())); + const float pVoxel0px1py0pz = static_cast(convertToDnsity(volIter.peekVoxel0px1py0pz())); + const float pVoxel0px1py1pz = static_cast(convertToDnsity(volIter.peekVoxel0px1py1pz())); - const float pVoxel1px1ny1nz = static_cast(volIter.peekVoxel1px1ny1nz().getDensity()); - const float pVoxel1px1ny0pz = static_cast(volIter.peekVoxel1px1ny0pz().getDensity()); - const float pVoxel1px1ny1pz = static_cast(volIter.peekVoxel1px1ny1pz().getDensity()); - const float pVoxel1px0py1nz = static_cast(volIter.peekVoxel1px0py1nz().getDensity()); - const float pVoxel1px0py0pz = static_cast(volIter.peekVoxel1px0py0pz().getDensity()); - const float pVoxel1px0py1pz = static_cast(volIter.peekVoxel1px0py1pz().getDensity()); - const float pVoxel1px1py1nz = static_cast(volIter.peekVoxel1px1py1nz().getDensity()); - const float pVoxel1px1py0pz = static_cast(volIter.peekVoxel1px1py0pz().getDensity()); - const float pVoxel1px1py1pz = static_cast(volIter.peekVoxel1px1py1pz().getDensity()); + const float pVoxel1px1ny1nz = static_cast(convertToDnsity(volIter.peekVoxel1px1ny1nz())); + const float pVoxel1px1ny0pz = static_cast(convertToDnsity(volIter.peekVoxel1px1ny0pz())); + const float pVoxel1px1ny1pz = static_cast(convertToDnsity(volIter.peekVoxel1px1ny1pz())); + const float pVoxel1px0py1nz = static_cast(convertToDnsity(volIter.peekVoxel1px0py1nz())); + const float pVoxel1px0py0pz = static_cast(convertToDnsity(volIter.peekVoxel1px0py0pz())); + const float pVoxel1px0py1pz = static_cast(convertToDnsity(volIter.peekVoxel1px0py1pz())); + const float pVoxel1px1py1nz = static_cast(convertToDnsity(volIter.peekVoxel1px1py1nz())); + const float pVoxel1px1py0pz = static_cast(convertToDnsity(volIter.peekVoxel1px1py0pz())); + const float pVoxel1px1py1pz = static_cast(convertToDnsity(volIter.peekVoxel1px1py1pz())); const float xGrad(- weights[0][0][0] * pVoxel1nx1ny1nz - weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] * @@ -205,6 +221,9 @@ namespace PolyVox Region m_regVolumeCropped;*/ Region m_regSlicePrevious; Region m_regSliceCurrent; + + //Our threshold value + typename VoxelTypeTraits::DensityType m_tThreshold; }; } diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl index 456be614..e4c975bd 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl @@ -24,11 +24,12 @@ freely, subject to the following restrictions: namespace PolyVox { template< template class VolumeType, typename VoxelType> - SurfaceExtractor::SurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh* result) + SurfaceExtractor::SurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh* result, typename VoxelTypeTraits::DensityType tThreshold) :m_volData(volData) ,m_sampVolume(volData) ,m_meshCurrent(result) ,m_regSizeInVoxels(region) + ,m_tThreshold(tThreshold) { //m_regSizeInVoxels.cropTo(m_volData->getEnclosingRegion()); m_regSizeInCells = m_regSizeInVoxels; @@ -229,7 +230,7 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ; - if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; + if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } else //previous X not available { @@ -247,8 +248,8 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ; - if (v011.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 64; - if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; + if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; + if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } } else //previous Y not available @@ -269,8 +270,8 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ; - if (v101.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 32; - if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; + if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; + if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } else //previous X not available { @@ -283,10 +284,10 @@ namespace PolyVox uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; iCubeIndex = iPreviousCubeIndexZ >> 4; - if (v001.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 16; - if (v101.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 32; - if (v011.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 64; - if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; + if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; + if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; + if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; + if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } } } @@ -311,8 +312,8 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; - if (v110.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 8; - if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; + if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; + if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } else //previous X not available { @@ -329,10 +330,10 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexY; - if (v010.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 4; - if (v110.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 8; - if (v011.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 64; - if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; + if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4; + if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; + if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; + if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } } else //previous Y not available @@ -352,10 +353,10 @@ namespace PolyVox iCubeIndex = iPreviousCubeIndexX; - if (v100.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 2; - if (v110.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 8; - if (v101.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 32; - if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; + if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2; + if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; + if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; + if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } else //previous X not available { @@ -369,14 +370,14 @@ namespace PolyVox v011 = m_sampVolume.peekVoxel0px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz(); - if (v000.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 1; - if (v100.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 2; - if (v010.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 4; - if (v110.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 8; - if (v001.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 16; - if (v101.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 32; - if (v011.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 64; - if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; + if (convertToDensity(v000) < m_tThreshold) iCubeIndex |= 1; + if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2; + if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4; + if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; + if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; + if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; + if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; + if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; } } } @@ -432,12 +433,9 @@ namespace PolyVox const VoxelType v100 = m_sampVolume.getVoxel(); const Vector3DFloat n100 = computeCentralDifferenceGradient(m_sampVolume); - //float fInterp = static_cast(v100.getDensity() - VoxelType::getMinDensity()) / static_cast(VoxelType::getMaxDensity() - VoxelType::getMinDensity()); - float fInterp = static_cast(VoxelType::getThreshold() - v000.getDensity()) / static_cast(v100.getDensity() - v000.getDensity()); - //fInterp = 0.5f; + float fInterp = static_cast(m_tThreshold - convertToDensity(v000)) / static_cast(convertToDensity(v100) - convertToDensity(v000)); const Vector3DFloat v3dPosition(static_cast(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()) + fInterp, static_cast(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast(iZVolSpace - m_regSizeInCells.getLowerCorner().getZ())); - //const Vector3DFloat v3dNormal(v000.getDensity() > v100.getDensity() ? 1.0f : -1.0f,0.0,0.0); Vector3DFloat v3dNormal = (n100*fInterp) + (n000*(1-fInterp)); v3dNormal.normalise(); @@ -445,7 +443,9 @@ namespace PolyVox //Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of //material IDs does not make sense). We take the largest, so that if we are working on a material-only //volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component. - const uint32_t uMaterial = (std::max)(v000.getMaterial(), v100.getMaterial()); + uint32_t uMaterial000 = convertToMaterial(v000); + uint32_t uMaterial100 = convertToMaterial(v100); + uint32_t uMaterial = (std::max)(uMaterial000, uMaterial100); PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast(uMaterial)); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); @@ -459,11 +459,9 @@ namespace PolyVox const VoxelType v010 = m_sampVolume.getVoxel(); const Vector3DFloat n010 = computeCentralDifferenceGradient(m_sampVolume); - float fInterp = static_cast(VoxelType::getThreshold() - v000.getDensity()) / static_cast(v010.getDensity() - v000.getDensity()); - //fInterp = 0.5f; + float fInterp = static_cast(m_tThreshold - convertToDensity(v000)) / static_cast(convertToDensity(v010) - convertToDensity(v000)); const Vector3DFloat v3dPosition(static_cast(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()) + fInterp, static_cast(iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ())); - //const Vector3DFloat v3dNormal(0.0,v000.getDensity() > v010.getDensity() ? 1.0f : -1.0f,0.0); Vector3DFloat v3dNormal = (n010*fInterp) + (n000*(1-fInterp)); v3dNormal.normalise(); @@ -471,7 +469,9 @@ namespace PolyVox //Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of //material IDs does not make sense). We take the largest, so that if we are working on a material-only //volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component. - const uint32_t uMaterial = (std::max)(v000.getMaterial(), v010.getMaterial()); + uint32_t uMaterial000 = convertToMaterial(v000); + uint32_t uMaterial010 = convertToMaterial(v010); + uint32_t uMaterial = (std::max)(uMaterial000, uMaterial010); PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast(uMaterial)); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); @@ -485,11 +485,9 @@ namespace PolyVox const VoxelType v001 = m_sampVolume.getVoxel(); const Vector3DFloat n001 = computeCentralDifferenceGradient(m_sampVolume); - float fInterp = static_cast(VoxelType::getThreshold() - v000.getDensity()) / static_cast(v001.getDensity() - v000.getDensity()); - //fInterp = 0.5f; + float fInterp = static_cast(m_tThreshold - convertToDensity(v000)) / static_cast(convertToDensity(v001) - convertToDensity(v000)); const Vector3DFloat v3dPosition(static_cast(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast(iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ()) + fInterp); - //const Vector3DFloat v3dNormal(0.0,0.0,v000.getDensity() > v001.getDensity() ? 1.0f : -1.0f); Vector3DFloat v3dNormal = (n001*fInterp) + (n000*(1-fInterp)); v3dNormal.normalise(); @@ -497,7 +495,9 @@ namespace PolyVox //Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of //material IDs does not make sense). We take the largest, so that if we are working on a material-only //volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component. - const uint32_t uMaterial = (std::max)(v000.getMaterial(), v001.getMaterial()); + uint32_t uMaterial000 = convertToMaterial(v000); + uint32_t uMaterial001 = convertToMaterial(v001); + uint32_t uMaterial = (std::max)(uMaterial000, uMaterial001); PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast(uMaterial)); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); @@ -531,8 +531,8 @@ namespace PolyVox m_sampVolume.setPosition(iXVolSpace,iYVolSpace,iZVolSpace); //Current position - const uint32_t uXRegSpace = m_sampVolume.getPosX() - m_regSizeInVoxels.getLowerCorner().getX(); - const uint32_t uYRegSpace = m_sampVolume.getPosY() - m_regSizeInVoxels.getLowerCorner().getY(); + const uint32_t uXRegSpace = m_sampVolume.getPosition().getX() - m_regSizeInVoxels.getLowerCorner().getX(); + const uint32_t uYRegSpace = m_sampVolume.getPosition().getY() - m_regSizeInVoxels.getLowerCorner().getY(); //Determine the index into the edge table which tells us which vertices are inside of the surface uint8_t iCubeIndex = pPreviousBitmask[uXRegSpace][uYRegSpace]; @@ -613,13 +613,6 @@ namespace PolyVox if((ind0 != -1) && (ind1 != -1) && (ind2 != -1)) { - assert(ind0 >= 0); - assert(ind1 >= 0); - assert(ind2 >= 0); - - assert(ind0 < 1000000); - assert(ind1 < 1000000); - assert(ind2 < 1000000); m_meshCurrent->addTriangle(ind0, ind1, ind2); } }//For each triangle diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceMesh.inl b/library/PolyVoxCore/include/PolyVoxCore/SurfaceMesh.inl index f21ad6b0..45d24ada 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SurfaceMesh.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/SurfaceMesh.inl @@ -100,6 +100,11 @@ namespace PolyVox template void SurfaceMesh::addTriangle(uint32_t index0, uint32_t index1, uint32_t index2) { + //Make sure the specified indices correspond to valid vertices. + assert(index0 < m_vecVertices.size()); + assert(index1 < m_vecVertices.size()); + assert(index2 < m_vecVertices.size()); + m_vecTriangleIndices.push_back(index0); m_vecTriangleIndices.push_back(index1); m_vecTriangleIndices.push_back(index2); @@ -108,6 +113,11 @@ namespace PolyVox template void SurfaceMesh::addTriangleCubic(uint32_t index0, uint32_t index1, uint32_t index2) { + //Make sure the specified indices correspond to valid vertices. + assert(index0 < m_vecVertices.size()); + assert(index1 < m_vecVertices.size()); + assert(index2 < m_vecVertices.size()); + m_vecTriangleIndices.push_back(index0); m_vecTriangleIndices.push_back(index1); m_vecTriangleIndices.push_back(index2); @@ -475,4 +485,4 @@ namespace PolyVox m_vecVertices[ct].setPosition(position); } } -} \ No newline at end of file +} diff --git a/library/PolyVoxCore/include/PolyVoxCore/VolumeResampler.inl b/library/PolyVoxCore/include/PolyVoxCore/VolumeResampler.inl index 9a5ffdeb..2d030adf 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/VolumeResampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/VolumeResampler.inl @@ -21,6 +21,8 @@ freely, subject to the following restrictions: distribution. *******************************************************************************/ +#include "PolyVoxImpl/Utility.h" + namespace PolyVox { template< template class SrcVolumeType, template class DestVolumeType, typename VoxelType> @@ -110,14 +112,14 @@ namespace PolyVox VoxelType voxel110 = sampler.peekVoxel1px1py0pz(); VoxelType voxel111 = sampler.peekVoxel1px1py1pz(); - uint8_t voxel000Den = voxel000.getDensity(); - uint8_t voxel001Den = voxel001.getDensity(); - uint8_t voxel010Den = voxel010.getDensity(); - uint8_t voxel011Den = voxel011.getDensity(); - uint8_t voxel100Den = voxel100.getDensity(); - uint8_t voxel101Den = voxel101.getDensity(); - uint8_t voxel110Den = voxel110.getDensity(); - uint8_t voxel111Den = voxel111.getDensity(); + typename VoxelTypeTraits::DensityType voxel000Den = convertToDensity(voxel000); + typename VoxelTypeTraits::DensityType voxel001Den = convertToDensity(voxel001); + typename VoxelTypeTraits::DensityType voxel010Den = convertToDensity(voxel010); + typename VoxelTypeTraits::DensityType voxel011Den = convertToDensity(voxel011); + typename VoxelTypeTraits::DensityType voxel100Den = convertToDensity(voxel100); + typename VoxelTypeTraits::DensityType voxel101Den = convertToDensity(voxel101); + typename VoxelTypeTraits::DensityType voxel110Den = convertToDensity(voxel110); + typename VoxelTypeTraits::DensityType voxel111Den = convertToDensity(voxel111); //FIXME - should accept all float parameters, but GCC complains? double dummy; @@ -125,10 +127,11 @@ namespace PolyVox sy = modf(sy, &dummy); sz = modf(sz, &dummy); - uint8_t uInterpolatedDensity = trilinearlyInterpolate(voxel000Den,voxel100Den,voxel010Den,voxel110Den,voxel001Den,voxel101Den,voxel011Den,voxel111Den,sx,sy,sz); + typename VoxelTypeTraits::DensityType uInterpolatedDensity = trilinearlyInterpolate(voxel000Den,voxel100Den,voxel010Den,voxel110Den,voxel001Den,voxel101Den,voxel011Den,voxel111Den,sx,sy,sz); VoxelType result; - result.setDensity(uInterpolatedDensity); + //result.setDensity(uInterpolatedDensity); + result = uInterpolatedDensity; m_pVolDst->setVoxelAt(dx,dy,dz,result); } diff --git a/library/PolyVoxCore/include/PolyVoxCore/Voxel.h b/library/PolyVoxCore/include/PolyVoxCore/Voxel.h index 0d458283..82c228f9 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Voxel.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Voxel.h @@ -30,37 +30,15 @@ freely, subject to the following restrictions: #include namespace PolyVox -{ - /// This class represents a voxel - //////////////////////////////////////////////////////////////////////////////// - /// Detailed description... - //////////////////////////////////////////////////////////////////////////////// - template - class Voxel - { - public: - // We expose DensityType and MaterialType in this way so that, when code is - // templatised on voxel type, it can determine the underlying storage type - // using code such as 'VoxelType::DensityType value = voxel.getDensity()' - // or 'VoxelType::MaterialType value = voxel.getMaterial()'. - typedef DenType DensityType; - typedef MatType MaterialType; - - DensityType getDensity() const throw() { assert(false); return 0; } - MaterialType getMaterial() const throw() { assert(false); return 0; } - - void setDensity(DensityType uDensity) { assert(false); } - void setMaterial(MaterialType /*uMaterial*/) { assert(false); } - }; - +{ // Various properties of the voxel types can be expressed via types traits, similar to the way std::numeric_limits is implemented. // This has some advantages compared to storing the properties directly in the voxel class. For example, by using traits it is possible // to also apply these properties to primative types which might be desirable (the Volume classes do accept primative types as template - // parameters). Also, properties such as MinDensity and MaxDensity would be difficult to represent though class members because they + // parameters). Also, properties such as minDensity() and maxDensity() would be difficult to represent though class members because they // depend ont the type (float has a very different range from int8_t for example). // // The properties are currently exposed as constants because we need access to them at compile time. Ideally we would like to make them - // functions flagged with 'constexpr' as we could then make use of the max() and min() functions in std::numric_limits, but this is not + // functions flagged with 'constexpr' as we could then make use of the max() and min() functions in std::numeric_limits, but this is not // widely supported by compilers yet. We may change this in the future. // // Syntax for templatised traits classes: http://stackoverflow.com/q/8606302/849083 @@ -68,10 +46,22 @@ namespace PolyVox class VoxelTypeTraits { public: - const static typename Type::DensityType MinDensity; - const static typename Type::DensityType MaxDensity; + typedef uint8_t DensityType; + typedef uint8_t MaterialType; + + // These default implementations return an int32_t rather than void so that the result can be + // assigned to a variable for all voxel types (even those without density components). Calls + // to these functions should be protected by calls to hasDensity(), but the compiler still + // needs to ensure the assignment is compilable even if hasDensity() returns false. + static int32_t minDensity() { assert(false); return 0; } + static int32_t maxDensity() { assert(false); return 0; } }; + template + typename VoxelTypeTraits::DensityType convertToDensity(VoxelType voxel) + { + return voxel; + } } #endif //__PolyVox_Voxel_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/VoxelFilters.h b/library/PolyVoxCore/include/PolyVoxCore/VoxelFilters.h index 17d65e59..8e338e4f 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/VoxelFilters.h +++ b/library/PolyVoxCore/include/PolyVoxCore/VoxelFilters.h @@ -32,4 +32,4 @@ namespace PolyVox float computeSmoothedVoxel(typename VolumeType::Sampler& volIter); } -#endif \ No newline at end of file +#endif diff --git a/library/PolyVoxCore/include/PolyVoxImpl/AStarPathfinderImpl.h b/library/PolyVoxCore/include/PolyVoxImpl/AStarPathfinderImpl.h index e4a03498..03199f7e 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/AStarPathfinderImpl.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/AStarPathfinderImpl.h @@ -221,4 +221,4 @@ namespace PolyVox //bool operator<(const AllNodesContainer::iterator& lhs, const AllNodesContainer::iterator& rhs); } -#endif //__PolyVox_AStarPathfinderImpl_H__ \ No newline at end of file +#endif //__PolyVox_AStarPathfinderImpl_H__ diff --git a/library/PolyVoxCore/include/PolyVoxImpl/ArraySizesImpl.inl b/library/PolyVoxCore/include/PolyVoxImpl/ArraySizesImpl.inl index 727a885a..99f6ef67 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/ArraySizesImpl.inl +++ b/library/PolyVoxCore/include/PolyVoxImpl/ArraySizesImpl.inl @@ -43,4 +43,4 @@ namespace PolyVox std::copy(&pSizes[0],&pSizes[N-1],m_pSizes); m_pSizes[N-1]=uSize; } -}//namespace PolyVox \ No newline at end of file +}//namespace PolyVox diff --git a/library/PolyVoxCore/include/PolyVoxImpl/MarchingCubesTables.h b/library/PolyVoxCore/include/PolyVoxImpl/MarchingCubesTables.h index 59745a82..da199fcd 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/MarchingCubesTables.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/MarchingCubesTables.h @@ -28,8 +28,8 @@ freely, subject to the following restrictions: namespace PolyVox { - extern POLYVOX_API int edgeTable[256]; - extern POLYVOX_API int triTable[256][16]; + extern const POLYVOX_API int edgeTable[256]; + extern const POLYVOX_API int triTable[256][16]; } #endif diff --git a/library/PolyVoxCore/include/PolyVoxImpl/SubArray.h b/library/PolyVoxCore/include/PolyVoxImpl/SubArray.h index 9055429a..06b235a9 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/SubArray.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/SubArray.h @@ -85,4 +85,4 @@ namespace PolyVox #include "PolyVoxImpl/SubArray.inl" -#endif //__PolyVox_SubArray_H__ \ No newline at end of file +#endif //__PolyVox_SubArray_H__ diff --git a/library/PolyVoxCore/include/PolyVoxImpl/TypeDef.h b/library/PolyVoxCore/include/PolyVoxImpl/TypeDef.h index 10745e8c..d8ab9229 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/TypeDef.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/TypeDef.h @@ -76,6 +76,9 @@ freely, subject to the following restrictions: #define polyvox_bind boost::bind #define polyvox_placeholder_1 _1 #define polyvox_placeholder_2 _2 + + #include + #define static_assert BOOST_STATIC_ASSERT //As long as we're requiring boost, we'll use it to compensate @@ -98,6 +101,7 @@ freely, subject to the following restrictions: #define polyvox_placeholder_1 std::placeholders::_1 #define polyvox_placeholder_2 std::placeholders::_2 #define polyvox_hash std::hash + //#define static_assert static_assert //we can use this #endif #endif diff --git a/library/PolyVoxCore/source/AStarPathfinder.cpp b/library/PolyVoxCore/source/AStarPathfinder.cpp index 95c680a1..fcb58ca2 100644 --- a/library/PolyVoxCore/source/AStarPathfinder.cpp +++ b/library/PolyVoxCore/source/AStarPathfinder.cpp @@ -64,4 +64,4 @@ namespace PolyVox Vector3DInt32(+1, +1, -1), Vector3DInt32(+1, +1, +1) }; -} \ No newline at end of file +} diff --git a/library/PolyVoxCore/source/ArraySizes.cpp b/library/PolyVoxCore/source/ArraySizes.cpp index f6b7370f..4328ad3c 100644 --- a/library/PolyVoxCore/source/ArraySizes.cpp +++ b/library/PolyVoxCore/source/ArraySizes.cpp @@ -52,4 +52,4 @@ namespace PolyVox { return m_pSizes; } -} \ No newline at end of file +} diff --git a/library/PolyVoxCore/source/Density.cpp b/library/PolyVoxCore/source/Density.cpp index 781e4d3b..976dd04a 100644 --- a/library/PolyVoxCore/source/Density.cpp +++ b/library/PolyVoxCore/source/Density.cpp @@ -1,59 +1,33 @@ -/******************************************************************************* -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/Density.h" - -#include //Can't use as we need compile time constants. - -namespace PolyVox -{ - template<> - const int8_t VoxelTypeTraits< Density >::MinDensity = -127; - template<> - const int8_t VoxelTypeTraits< Density >::MaxDensity = 127; - - template<> - const uint8_t VoxelTypeTraits< Density >::MinDensity = 0; - template<> - const uint8_t VoxelTypeTraits< Density >::MaxDensity = 255; - - template<> - const int16_t VoxelTypeTraits< Density >::MinDensity = -32767; - template<> - const int16_t VoxelTypeTraits< Density >::MaxDensity = 32767; - - template<> - const uint16_t VoxelTypeTraits< Density >::MinDensity = 0; - template<> - const uint16_t VoxelTypeTraits< Density >::MaxDensity = 65535; - - template<> - const float VoxelTypeTraits< Density >::MinDensity = FLT_MIN; - template<> - const float VoxelTypeTraits< Density >::MaxDensity = FLT_MAX; - - template<> - const double VoxelTypeTraits< Density >::MinDensity = DBL_MIN; - template<> - const double VoxelTypeTraits< Density >::MaxDensity = DBL_MAX; -} \ No newline at end of file +/******************************************************************************* +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/Density.h" + +namespace PolyVox +{ + template<> + typename VoxelTypeTraits::DensityType convertToDensity(Density8 voxel) + { + return voxel.getDensity(); + } +} diff --git a/library/PolyVoxCore/source/Log.cpp b/library/PolyVoxCore/source/Log.cpp index 37c91f12..929fd951 100644 --- a/library/PolyVoxCore/source/Log.cpp +++ b/library/PolyVoxCore/source/Log.cpp @@ -26,4 +26,4 @@ freely, subject to the following restrictions: namespace PolyVox { void (*logHandler)(std::string, int severity) = 0; -} \ No newline at end of file +} diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceTypes.h b/library/PolyVoxCore/source/Material.cpp similarity index 62% rename from library/PolyVoxCore/include/PolyVoxCore/SurfaceTypes.h rename to library/PolyVoxCore/source/Material.cpp index 197a07ae..27d34678 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SurfaceTypes.h +++ b/library/PolyVoxCore/source/Material.cpp @@ -1,42 +1,33 @@ -/******************************************************************************* -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_SurfaceTypes_H__ -#define __PolyVox_SurfaceTypes_H__ - -#include - -namespace PolyVox -{ - class SurfaceVertex; - typedef std::set::iterator SurfaceVertexIterator; - typedef std::set::const_iterator SurfaceVertexConstIterator; - class SurfaceTriangle; - typedef std::set::iterator SurfaceTriangleIterator; - typedef std::set::const_iterator SurfaceTriangleConstIterator; - class SurfaceEdge; - typedef std::set::iterator SurfaceEdgeIterator; - typedef std::set::const_iterator SurfaceEdgeConstIterator; -} - -#endif +/******************************************************************************* +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/Material.h" + +namespace PolyVox +{ + //template<> + //typename VoxelTypeTraits::DensityType convertToDensity(Material8 voxel) + //{ + // return voxel.getDensity(); + //} +} diff --git a/library/PolyVoxCore/source/MaterialDensityPair.cpp b/library/PolyVoxCore/source/MaterialDensityPair.cpp index a937aa85..00a34a2b 100644 --- a/library/PolyVoxCore/source/MaterialDensityPair.cpp +++ b/library/PolyVoxCore/source/MaterialDensityPair.cpp @@ -25,13 +25,27 @@ freely, subject to the following restrictions: namespace PolyVox { - //template - //const Type VoxelTypeTraits< MaterialDensityPair >::MinDensity = 0; - //template - //const Type VoxelTypeTraits< Type >::MaxDensity = (0x01 << NoOfDensityBits) - 1; - template<> - const uint8_t VoxelTypeTraits< MaterialDensityPair44 >::MinDensity = 0; + typename VoxelTypeTraits::DensityType convertToDensity(MaterialDensityPair44 voxel) + { + return voxel.getDensity(); + } + template<> - const uint8_t VoxelTypeTraits< MaterialDensityPair44 >::MaxDensity = 15; -} + typename VoxelTypeTraits::DensityType convertToDensity(MaterialDensityPair88 voxel) + { + return voxel.getDensity(); + } + + template<> + typename VoxelTypeTraits::MaterialType convertToMaterial(MaterialDensityPair44 voxel) + { + return voxel.getMaterial(); + } + + template<> + typename VoxelTypeTraits::MaterialType convertToMaterial(MaterialDensityPair88 voxel) + { + return voxel.getMaterial(); + } +} diff --git a/library/PolyVoxCore/source/PolyVoxImpl/MarchingCubesTables.cpp b/library/PolyVoxCore/source/PolyVoxImpl/MarchingCubesTables.cpp index b9175671..c0e069f6 100644 --- a/library/PolyVoxCore/source/PolyVoxImpl/MarchingCubesTables.cpp +++ b/library/PolyVoxCore/source/PolyVoxImpl/MarchingCubesTables.cpp @@ -30,8 +30,8 @@ freely, subject to the following restrictions: namespace PolyVox { - int edgeTable[256]= - { + const int edgeTable[256]= + { 0x000, 0x109, 0x203, 0x30a, 0x80c, 0x905, 0xa0f, 0xb06, 0x406, 0x50f, 0x605, 0x70c, 0xc0a, 0xd03, 0xe09, 0xf00, 0x190, 0x099, 0x393, 0x29a, 0x99c, 0x895, 0xb9f, 0xa96, @@ -66,7 +66,7 @@ namespace PolyVox 0xb06, 0xa0f, 0x905, 0x80c, 0x30a, 0x203, 0x109, 0x000 }; - int triTable[256][16] = + const int triTable[256][16] = { {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, diff --git a/library/PolyVoxCore/source/PolyVoxImpl/RandomVectors.cpp b/library/PolyVoxCore/source/PolyVoxImpl/RandomVectors.cpp index 81c3c4f3..532adf14 100644 --- a/library/PolyVoxCore/source/PolyVoxImpl/RandomVectors.cpp +++ b/library/PolyVoxCore/source/PolyVoxImpl/RandomVectors.cpp @@ -1052,4 +1052,4 @@ namespace PolyVox Vector3DFloat(+0.862667f, +0.053377f, +0.652333f), Vector3DFloat(-0.002289f, +0.568834f, -0.069185f) }; -} \ No newline at end of file +} diff --git a/library/PolyVoxCore/source/SimpleInterface.cpp b/library/PolyVoxCore/source/SimpleInterface.cpp index f241747a..3a61a51f 100644 --- a/library/PolyVoxCore/source/SimpleInterface.cpp +++ b/library/PolyVoxCore/source/SimpleInterface.cpp @@ -23,6 +23,10 @@ freely, subject to the following restrictions: #include "PolyVoxCore/SimpleInterface.h" +//DOESN'T BELONG HERE - JUST FOR TESTING!! +#include "PolyVoxCore/Density.h" +#include "PolyVoxCore/MaterialDensityPair.h" + namespace PolyVox { void extractCubicMesh(Volume& volume, const Region& region, Mesh& resultMesh) diff --git a/library/PolyVoxCore/source/SurfaceEdge.cpp b/library/PolyVoxCore/source/SurfaceEdge.cpp deleted file mode 100644 index e1f5df8a..00000000 --- a/library/PolyVoxCore/source/SurfaceEdge.cpp +++ /dev/null @@ -1,129 +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 - -#include "SurfaceEdge.h" -#include "SurfaceTriangle.h" -#include "SurfaceVertex.h" - -namespace PolyVox -{ - SurfaceEdge::SurfaceEdge(const SurfaceVertexIterator& targetToSet,const SurfaceVertexIterator& sourceToSet) - { - target = targetToSet; - source = sourceToSet; - } - - std::string SurfaceEdge::tostring(void) - { - std::stringstream ss; - ss << "SurfaceEdge: Target Vertex = " << target->tostring() << "Source Vertex = " << source->tostring(); - return ss.str(); - } - - bool operator == (const SurfaceEdge& lhs, const SurfaceEdge& rhs) - { - //Vertices are unique in the set, so if the two positions are the same the - //two iterators must also be the same. So we just check the iterators. - return - ( - (lhs.target == rhs.target) && - (lhs.source == rhs.source) - ); - } - - bool SurfaceEdge::isDegenerate(void) - { - return (target == source); - } - - bool operator < (const SurfaceEdge& lhs, const SurfaceEdge& rhs) - { - //Unlike the equality operator, we can't compare iterators. - //So dereference and compare the results. - if ((*lhs.target) < (*rhs.target)) - return true; - if ((*rhs.target) < (*lhs.target)) - return false; - - if ((*lhs.source) < (*rhs.source)) - return true; - if ((*rhs.source) < (*lhs.source)) - return false; - - return false; - } - - const SurfaceVertexIterator& SurfaceEdge::getTarget(void) const - { - return target; - } - - const SurfaceVertexIterator& SurfaceEdge::getSource(void) const - { - return source; - } - - void SurfaceEdge::pairWithOtherHalfEdge(const SurfaceEdgeIterator& otherHalfEdgeToPair) - { - otherHalfEdge = otherHalfEdgeToPair; - previousHalfEdge = otherHalfEdgeToPair; - nextHalfEdge = otherHalfEdgeToPair; - } - - const SurfaceEdgeIterator& SurfaceEdge::getOtherHalfEdge(void) const - { - return otherHalfEdge; - } - - const SurfaceEdgeIterator& SurfaceEdge::getPreviousHalfEdge(void) const - { - return previousHalfEdge; - } - - const SurfaceEdgeIterator& SurfaceEdge::getNextHalfEdge(void) const - { - return nextHalfEdge; - } - - const SurfaceTriangleIterator& SurfaceEdge::getTriangle(void) const - { - return triangle; - } - - void SurfaceEdge::setPreviousHalfEdge(const SurfaceEdgeIterator& previousHalfEdgeToSet) - { - previousHalfEdge = previousHalfEdgeToSet; - } - - void SurfaceEdge::setNextHalfEdge(const SurfaceEdgeIterator& nextHalfEdgeToSet) - { - nextHalfEdge = nextHalfEdgeToSet; - } - - void SurfaceEdge::setTriangle(const SurfaceTriangleIterator& triangleToSet) - { - triangle = triangleToSet; - } -} diff --git a/library/PolyVoxCore/source/VoxelFilters.cpp b/library/PolyVoxCore/source/VoxelFilters.cpp index 45c5176c..19881cd6 100644 --- a/library/PolyVoxCore/source/VoxelFilters.cpp +++ b/library/PolyVoxCore/source/VoxelFilters.cpp @@ -63,4 +63,4 @@ namespace PolyVox sum /= 27.0f; return sum; } -} \ No newline at end of file +} diff --git a/library/PolyVoxUtil/source/Dummy.cpp b/library/PolyVoxUtil/source/Dummy.cpp index 4aca19e4..b5bbf04f 100644 --- a/library/PolyVoxUtil/source/Dummy.cpp +++ b/library/PolyVoxUtil/source/Dummy.cpp @@ -13,4 +13,4 @@ namespace PolyVox { return x; } -} \ No newline at end of file +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 506f641e..4f1f6179 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -59,10 +59,17 @@ ADD_TEST(VolumeSizeTest ${LATEST_TEST} testSize) CREATE_TEST(testmaterial.h testmaterial.cpp testmaterial) ADD_TEST(MaterialTestCompile ${LATEST_TEST} testCompile) +# Raycast tests +CREATE_TEST(TestRaycast.h TestRaycast.cpp TestRaycast) +ADD_TEST(RaycastExecuteTest ${LATEST_TEST} testExecute) + # Region tests CREATE_TEST(TestRegion.h TestRegion.cpp TestRegion) ADD_TEST(RegionEqualityTest ${LATEST_TEST} testEquality) +CREATE_TEST(TestSurfaceExtractor.h TestSurfaceExtractor.cpp TestSurfaceExtractor) +ADD_TEST(SurfaceExtractorExecuteTest ${LATEST_TEST} testExecute) + #Vector tests CREATE_TEST(testvector.h testvector.cpp testvector) ADD_TEST(VectorLengthTest ${LATEST_TEST} testLength) @@ -73,6 +80,6 @@ ADD_TEST(VectorEqualityTest ${LATEST_TEST} testEquality) CREATE_TEST(TestVolumeSubclass.h TestVolumeSubclass.cpp TestVolumeSubclass) ADD_TEST(VolumeSubclassExtractSurfaceTest ${LATEST_TEST} testExtractSurface) -# ClassName tests +# Voxel tests CREATE_TEST(TestVoxels.h TestVoxels.cpp TestVoxels) -ADD_TEST(VoxelsTraitsTest ${LATEST_TEST} testTraits) +ADD_TEST(VoxelsTraitsTest ${LATEST_TEST} testVoxelTypeLimits) diff --git a/tests/TestAStarPathfinder.cpp b/tests/TestAStarPathfinder.cpp index 7df04a0a..d1c97dc7 100644 --- a/tests/TestAStarPathfinder.cpp +++ b/tests/TestAStarPathfinder.cpp @@ -31,40 +31,31 @@ freely, subject to the following restrictions: using namespace PolyVox; +template< template class VolumeType, typename VoxelType> +bool testVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos) +{ + //Voxels are considered valid candidates for the path if they are inside the volume... + if(volData->getEnclosingRegion().containsPoint(v3dPos) == false) + { + return false; + } + + VoxelType voxel = volData->getVoxelAt(v3dPos); + if(voxel != 0) + { + return false; + } + + return true; +} + void TestAStarPathfinder::testExecute() { //The expected path - //The following results work on Linux/GCC - const Vector3DInt32 expectedResult[] = - { - Vector3DInt32(0,0,0), - Vector3DInt32(1,1,1), - Vector3DInt32(2,2,1), - Vector3DInt32(3,3,1), - Vector3DInt32(4,4,1), - Vector3DInt32(4,5,1), - Vector3DInt32(5,6,1), - Vector3DInt32(6,7,2), - Vector3DInt32(7,8,3), - Vector3DInt32(8,9,3), - Vector3DInt32(9,10,3), - Vector3DInt32(10,11,3), - Vector3DInt32(11,12,4), - Vector3DInt32(12,13,5), - Vector3DInt32(13,13,6), - Vector3DInt32(13,13,7), - Vector3DInt32(13,13,8), - Vector3DInt32(13,13,9), - Vector3DInt32(14,14,10), - Vector3DInt32(14,14,11), - Vector3DInt32(14,14,12), - Vector3DInt32(14,14,13), - Vector3DInt32(15,15,14), - Vector3DInt32(15,15,15), - }; - + +#ifdef _MSC_VER //The following results work on Windows/VS2010 - /*const Vector3DInt32 expectedResult[] = + const Vector3DInt32 expectedResult[] = { Vector3DInt32(0,0,0), Vector3DInt32(1,1,1), @@ -90,10 +81,57 @@ void TestAStarPathfinder::testExecute() Vector3DInt32(13,13,13), Vector3DInt32(14,14,14), Vector3DInt32(15,15,15) - };*/ + }; - //Create an empty volume - RawVolume volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(15, 15, 15))); +#else + + //The following results work on Linux/GCC + const Vector3DInt32 expectedResult[] = + { + Vector3DInt32(0,0,0), + Vector3DInt32(1,1,1), + Vector3DInt32(2,1,2), + Vector3DInt32(3,1,3), + Vector3DInt32(4,1,4), + Vector3DInt32(5,1,5), + Vector3DInt32(6,1,5), + Vector3DInt32(7,2,6), + Vector3DInt32(8,3,7), + Vector3DInt32(9,3,8), + Vector3DInt32(10,3,9), + Vector3DInt32(11,3,10), + Vector3DInt32(12,4,11), + Vector3DInt32(12,5,11), + Vector3DInt32(13,6,12), + Vector3DInt32(13,7,13), + Vector3DInt32(13,8,13), + Vector3DInt32(13,9,13), + Vector3DInt32(14,10,14), + Vector3DInt32(14,11,14), + Vector3DInt32(14,12,14), + Vector3DInt32(15,13,15), + Vector3DInt32(15,14,15), + Vector3DInt32(15,15,15) + }; +#endif //_MSC_VER + + const int32_t uVolumeSideLength = 16; + + //Create a volume + RawVolume volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(uVolumeSideLength-1, uVolumeSideLength-1, uVolumeSideLength-1))); + + //Clear the volume + for(int z = 0; z < uVolumeSideLength; z++) + { + for(int y = 0; y < uVolumeSideLength; y++) + { + for(int x = 0; x < uVolumeSideLength; x++) + { + uint8_t solidVoxel(0); + volData.setVoxelAt(x,y,z,solidVoxel); + } + } + } //Place a solid cube in the middle of it for(int z = 4; z < 12; z++) @@ -102,7 +140,7 @@ void TestAStarPathfinder::testExecute() { for(int x = 4; x < 12; x++) { - Material8 solidVoxel(1); + uint8_t solidVoxel(1); volData.setVoxelAt(x,y,z,solidVoxel); } } @@ -112,8 +150,8 @@ void TestAStarPathfinder::testExecute() std::list result; //Create an AStarPathfinder - AStarPathfinderParams params(&volData, Vector3DInt32(0,0,0), Vector3DInt32(15,15,15), &result); - AStarPathfinder pathfinder(params); + AStarPathfinderParams params(&volData, Vector3DInt32(0,0,0), Vector3DInt32(15,15,15), &result, 1.0f, 10000, TwentySixConnected, &testVoxelValidator); + AStarPathfinder pathfinder(params); //Execute the pathfinder. pathfinder.execute(); diff --git a/tests/TestAmbientOcclusionGenerator.cpp b/tests/TestAmbientOcclusionGenerator.cpp index 6c2398cc..34f9df00 100644 --- a/tests/TestAmbientOcclusionGenerator.cpp +++ b/tests/TestAmbientOcclusionGenerator.cpp @@ -24,19 +24,23 @@ freely, subject to the following restrictions: #include "TestAmbientOcclusionGenerator.h" #include "PolyVoxCore/AmbientOcclusionCalculator.h" -#include "PolyVoxCore/Material.h" #include "PolyVoxCore/SimpleVolume.h" #include using namespace PolyVox; +bool isVoxelTransparent(uint8_t voxel) +{ + return voxel == 0; +} + void TestAmbientOcclusionGenerator::testExecute() { const int32_t g_uVolumeSideLength = 64; //Create empty volume - SimpleVolume volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1))); + SimpleVolume volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1))); //Create two solid walls at opposite sides of the volume for (int32_t z = 0; z < g_uVolumeSideLength; z++) @@ -47,8 +51,7 @@ void TestAmbientOcclusionGenerator::testExecute() { for (int32_t x = 0; x < g_uVolumeSideLength; x++) { - Material8 voxel(1); - volData.setVoxelAt(x, y, z, voxel); + volData.setVoxelAt(x, y, z, 1); } } } @@ -59,7 +62,7 @@ void TestAmbientOcclusionGenerator::testExecute() Array<3, uint8_t> ambientOcclusionResult(ArraySizes(g_uArraySideLength)(g_uArraySideLength)(g_uArraySideLength)); //Create the ambient occlusion calculator - AmbientOcclusionCalculator calculator(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 255); + AmbientOcclusionCalculator calculator(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 255, isVoxelTransparent); //Execute the calculator calculator.execute(); diff --git a/tests/TestLowPassFilter.cpp b/tests/TestLowPassFilter.cpp index 474e5021..914d3d13 100644 --- a/tests/TestLowPassFilter.cpp +++ b/tests/TestLowPassFilter.cpp @@ -63,24 +63,24 @@ void TestLowPassFilter::testExecute() pass1.execute(); std::cout << "Input volume:" << std::endl; - std::cout << "Voxel = " << static_cast(volData.getVoxelAt(0,0,0).getDensity()) << std::endl; // 32 - std::cout << "Voxel = " << static_cast(volData.getVoxelAt(1,1,1).getDensity()) << std::endl; // 0 - std::cout << "Voxel = " << static_cast(volData.getVoxelAt(2,2,2).getDensity()) << std::endl; // 3 - std::cout << "Voxel = " << static_cast(volData.getVoxelAt(3,3,3).getDensity()) << std::endl; // 0 - std::cout << "Voxel = " << static_cast(volData.getVoxelAt(4,4,4).getDensity()) << std::endl; // 32 - std::cout << "Voxel = " << static_cast(volData.getVoxelAt(5,5,5).getDensity()) << std::endl; // 0 - std::cout << "Voxel = " << static_cast(volData.getVoxelAt(6,6,6).getDensity()) << std::endl; // 32 - std::cout << "Voxel = " << static_cast(volData.getVoxelAt(7,7,7).getDensity()) << std::endl; // 0 + std::cout << "Voxel = " << static_cast(convertToDensity(volData.getVoxelAt(0,0,0))) << std::endl; // 32 + std::cout << "Voxel = " << static_cast(convertToDensity(volData.getVoxelAt(1,1,1))) << std::endl; // 0 + std::cout << "Voxel = " << static_cast(convertToDensity(volData.getVoxelAt(2,2,2))) << std::endl; // 3 + std::cout << "Voxel = " << static_cast(convertToDensity(volData.getVoxelAt(3,3,3))) << std::endl; // 0 + std::cout << "Voxel = " << static_cast(convertToDensity(volData.getVoxelAt(4,4,4))) << std::endl; // 32 + std::cout << "Voxel = " << static_cast(convertToDensity(volData.getVoxelAt(5,5,5))) << std::endl; // 0 + std::cout << "Voxel = " << static_cast(convertToDensity(volData.getVoxelAt(6,6,6))) << std::endl; // 32 + std::cout << "Voxel = " << static_cast(convertToDensity(volData.getVoxelAt(7,7,7))) << std::endl; // 0 std::cout << std::endl << "Output volume:" << std::endl; - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(0,0,0).getDensity()) << std::endl; // 4 - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(1,1,1).getDensity()) << std::endl; // 21 - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(2,2,2).getDensity()) << std::endl; // 10 - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(3,3,3).getDensity()) << std::endl; // 21 - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(4,4,4).getDensity()) << std::endl; // 10 - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(5,5,5).getDensity()) << std::endl; // 21 - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(6,6,6).getDensity()) << std::endl; // 10 - std::cout << "Voxel = " << static_cast(resultVolume.getVoxelAt(7,7,7).getDensity()) << std::endl; // 4 + std::cout << "Voxel = " << static_cast(convertToDensity(resultVolume.getVoxelAt(0,0,0))) << std::endl; // 4 + std::cout << "Voxel = " << static_cast(convertToDensity(resultVolume.getVoxelAt(1,1,1))) << std::endl; // 21 + std::cout << "Voxel = " << static_cast(convertToDensity(resultVolume.getVoxelAt(2,2,2))) << std::endl; // 10 + std::cout << "Voxel = " << static_cast(convertToDensity(resultVolume.getVoxelAt(3,3,3))) << std::endl; // 21 + std::cout << "Voxel = " << static_cast(convertToDensity(resultVolume.getVoxelAt(4,4,4))) << std::endl; // 10 + std::cout << "Voxel = " << static_cast(convertToDensity(resultVolume.getVoxelAt(5,5,5))) << std::endl; // 21 + std::cout << "Voxel = " << static_cast(convertToDensity(resultVolume.getVoxelAt(6,6,6))) << std::endl; // 10 + std::cout << "Voxel = " << static_cast(convertToDensity(resultVolume.getVoxelAt(7,7,7))) << std::endl; // 4 } QTEST_MAIN(TestLowPassFilter) diff --git a/tests/TestRaycast.cpp b/tests/TestRaycast.cpp new file mode 100644 index 00000000..72c5586e --- /dev/null +++ b/tests/TestRaycast.cpp @@ -0,0 +1,83 @@ +/******************************************************************************* +Copyright (c) 2010 Matt Williams + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*******************************************************************************/ + +#include "TestRaycast.h" + +#include "PolyVoxCore/Density.h" +#include "PolyVoxCore/Raycast.h" +#include "PolyVoxCore/SimpleVolume.h" + +#include "PolyVoxImpl/RandomUnitVectors.h" + +#include + +using namespace PolyVox; + +bool isPassableByRay(const SimpleVolume::Sampler& sampler) +{ + return sampler.getVoxel() <= 0; +} + +void TestRaycast::testExecute() +{ + const int32_t uVolumeSideLength = 32; + + //Create a hollow volume, with solid sides on x and y but with open ends in z. + SimpleVolume volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(uVolumeSideLength-1, uVolumeSideLength-1, uVolumeSideLength-1))); + for (int32_t z = 0; z < uVolumeSideLength; z++) + { + for (int32_t y = 0; y < uVolumeSideLength; y++) + { + for (int32_t x = 0; x < uVolumeSideLength; x++) + { + if((x == 0) || (x == uVolumeSideLength-1) || (y == 0) || (y == uVolumeSideLength-1)) + { + volData.setVoxelAt(x, y, z, 100); + } + else + { + volData.setVoxelAt(x, y, z, -100); + } + } + } + } + + //Cast rays from the centre. Roughly 2/3 should escape. + Vector3DFloat start (uVolumeSideLength / 2, uVolumeSideLength / 2, uVolumeSideLength / 2); + int hits = 0; + for(int ct = 0; ct < 1000000; ct++) + { + RaycastResult result; + Raycast raycast(&volData, start, randomUnitVectors[ct % 1024] * 1000.0f, result, isPassableByRay); + raycast.execute(); + if(result.foundIntersection) + { + hits++; + } + } + + //Check the number of hits. + QCOMPARE(hits, 687494); +} + +QTEST_MAIN(TestRaycast) diff --git a/tests/TestRaycast.h b/tests/TestRaycast.h new file mode 100644 index 00000000..ee6c3154 --- /dev/null +++ b/tests/TestRaycast.h @@ -0,0 +1,37 @@ +/******************************************************************************* +Copyright (c) 2010 Matt Williams + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*******************************************************************************/ + +#ifndef __PolyVox_TestRaycast_H__ +#define __PolyVox_TestRaycast_H__ + +#include + +class TestRaycast: public QObject +{ + Q_OBJECT + + private slots: + void testExecute(); +}; + +#endif diff --git a/tests/TestSurfaceExtractor.cpp b/tests/TestSurfaceExtractor.cpp new file mode 100644 index 00000000..2f633d76 --- /dev/null +++ b/tests/TestSurfaceExtractor.cpp @@ -0,0 +1,160 @@ +/******************************************************************************* +Copyright (c) 2010 Matt Williams + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*******************************************************************************/ + +#include "TestSurfaceExtractor.h" + +#include "PolyVoxCore/Density.h" +#include "PolyVoxCore/MaterialDensityPair.h" +#include "PolyVoxCore/SimpleVolume.h" +#include "PolyVoxCore/SurfaceExtractor.h" + +#include + +using namespace PolyVox; + + +// These 'writeDensityValueToVoxel' functions provide a unified interface for writting densities to primative and class voxel types. +// They are conceptually the inverse of the 'convertToDensity' function used by the SurfaceExtractor. They probably shouldn't be part +// of PolyVox, but they might be usful to other tests so we cold move them into a 'Tests.h' or something in the future. +template +void writeDensityValueToVoxel(typename VoxelTypeTraits::DensityType valueToWrite, VoxelType& voxel) +{ + voxel = valueToWrite; +} + +template<> +void writeDensityValueToVoxel(typename VoxelTypeTraits::DensityType valueToWrite, Density8& voxel) +{ + voxel.setDensity(valueToWrite); +} + +template<> +void writeDensityValueToVoxel(typename VoxelTypeTraits::DensityType valueToWrite, MaterialDensityPair88& voxel) +{ + voxel.setDensity(valueToWrite); +} + +template +void writeMaterialValueToVoxel(typename VoxelTypeTraits::MaterialType valueToWrite, VoxelType& voxel) +{ + //Most types don't have a material + return; +} + +template<> +void writeMaterialValueToVoxel(typename VoxelTypeTraits::MaterialType valueToWrite, MaterialDensityPair88& voxel) +{ + voxel.setMaterial(valueToWrite); +} + +// Runs the surface extractor for a given type. +template +void testForType(SurfaceMesh& result) +{ + const int32_t uVolumeSideLength = 32; + + //Create empty volume + SimpleVolume volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(uVolumeSideLength-1, uVolumeSideLength-1, uVolumeSideLength-1))); + + for (int32_t z = 0; z < uVolumeSideLength; z++) + { + for (int32_t y = 0; y < uVolumeSideLength; y++) + { + for (int32_t x = 0; x < uVolumeSideLength; x++) + { + VoxelType voxelValue; + //Create a density field which changes throughout the volume. + writeDensityValueToVoxel(x + y + z, voxelValue); + //Two different materials in two halves of the volume + writeMaterialValueToVoxel(z > uVolumeSideLength / 2 ? 42 : 79, voxelValue); + volData.setVoxelAt(x, y, z, voxelValue); + } + } + } + + SurfaceExtractor extractor(&volData, volData.getEnclosingRegion(), &result, 50); + extractor.execute(); +} + +void TestSurfaceExtractor::testExecute() +{ + const static uint32_t uExpectedVertices = 4731; + const static uint32_t uExpectedIndices = 12810; + const static uint32_t uMaterialToCheck = 3000; + const static float fExpectedMaterial = 42.0f; + const static float fNoMaterial = 1.0f; + + SurfaceMesh mesh; + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); + + testForType(mesh); + QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); + QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fExpectedMaterial); +} + +QTEST_MAIN(TestSurfaceExtractor) diff --git a/tests/TestSurfaceExtractor.h b/tests/TestSurfaceExtractor.h new file mode 100644 index 00000000..367d798e --- /dev/null +++ b/tests/TestSurfaceExtractor.h @@ -0,0 +1,37 @@ +/******************************************************************************* +Copyright (c) 2010 Matt Williams + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*******************************************************************************/ + +#ifndef __PolyVox_TestSurfaceExtractor_H__ +#define __PolyVox_TestSurfaceExtractor_H__ + +#include + +class TestSurfaceExtractor: public QObject +{ + Q_OBJECT + + private slots: + void testExecute(); +}; + +#endif diff --git a/tests/TestVoxels.cpp b/tests/TestVoxels.cpp index d505cd86..28d93a01 100644 --- a/tests/TestVoxels.cpp +++ b/tests/TestVoxels.cpp @@ -33,28 +33,49 @@ freely, subject to the following restrictions: using namespace PolyVox; -void TestVoxels::testTraits() -{ - int iValue; float fValue; //Used for temporary storage as the QCOMPARE maro struggles with the complex types. +void TestVoxels::testVoxelTypeLimits() +{ + // It's worth testing these as they are not all explictily defined (e.g. Density8 is just a + // typedef of DensityI8), and in the future we might define then with bitwise magic or something. + + /*QCOMPARE(VoxelTypeTraits::minDensity(), Density8::DensityType(0)); + QCOMPARE(VoxelTypeTraits::maxDensity(), Density8::DensityType(255)); + QCOMPARE(VoxelTypeTraits::minDensity(), DensityI8::DensityType(-127)); + QCOMPARE(VoxelTypeTraits::maxDensity(), DensityI8::DensityType(127)); - QCOMPARE(VoxelTypeTraits::MaxDensity, static_cast(0)); - QCOMPARE(VoxelTypeTraits::MaxDensity, static_cast(255)); + QCOMPARE(VoxelTypeTraits::minDensity(), DensityU8::DensityType(0)); + QCOMPARE(VoxelTypeTraits::maxDensity(), DensityU8::DensityType(255)); - fValue = VoxelTypeTraits::MinDensity; - QCOMPARE(fValue, FLT_MIN); - fValue = VoxelTypeTraits::MaxDensity; - QCOMPARE(fValue, FLT_MAX); + QCOMPARE(VoxelTypeTraits::minDensity(), Density16::DensityType(0)); + QCOMPARE(VoxelTypeTraits::maxDensity(), Density16::DensityType(65535)); - /*iValue = VoxelTypeTraits::MinDensity; + QCOMPARE(VoxelTypeTraits::minDensity(), DensityI16::DensityType(-32767)); + QCOMPARE(VoxelTypeTraits::maxDensity(), DensityI16::DensityType(32767)); + + QCOMPARE(VoxelTypeTraits::minDensity(), DensityU16::DensityType(0)); + QCOMPARE(VoxelTypeTraits::maxDensity(), DensityU16::DensityType(65535)); + + QCOMPARE(VoxelTypeTraits::minDensity(), -FLT_MAX); + QCOMPARE(VoxelTypeTraits::maxDensity(), FLT_MAX); + + QCOMPARE(VoxelTypeTraits::minDensity(), -DBL_MAX); + QCOMPARE(VoxelTypeTraits::maxDensity(), DBL_MAX);*/ + + /*fValue = VoxelTypeTraits::minDensity(); + QCOMPARE(fValue, -FLT_MAX); + fValue = VoxelTypeTraits::maxDensity(); + QCOMPARE(fValue, FLT_MAX);*/ + + /*iValue = VoxelTypeTraits::minDensity(); QCOMPARE(iValue, 0); - iValue = VoxelTypeTraits::MaxDensity; + iValue = VoxelTypeTraits::maxDensity(); QCOMPARE(iValue, 0);*/ - iValue = VoxelTypeTraits::MinDensity; + /*iValue = VoxelTypeTraits::minDensity(); QCOMPARE(iValue, 0); - iValue = VoxelTypeTraits::MaxDensity; - QCOMPARE(iValue, 15); + iValue = VoxelTypeTraits::maxDensity(); + QCOMPARE(iValue, 15);*/ } QTEST_MAIN(TestVoxels) diff --git a/tests/TestVoxels.h b/tests/TestVoxels.h index 0892b4c7..b301133a 100644 --- a/tests/TestVoxels.h +++ b/tests/TestVoxels.h @@ -31,7 +31,7 @@ class TestVoxels: public QObject Q_OBJECT private slots: - void testTraits(); + void testVoxelTypeLimits(); }; #endif