Merge branch 'master' of git@gitorious.org:polyvox/polyvox.git

This commit is contained in:
David Williams 2012-04-09 11:01:02 +02:00
commit 48717284d5
84 changed files with 1086 additions and 873 deletions

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -149,4 +149,4 @@ void OpenGLWidget::mouseMoveEvent(QMouseEvent* event)
m_LastFrameMousePos = m_CurrentMousePos;
update();
}
}

View File

@ -64,4 +64,4 @@ private:
int m_yRotation;
};
#endif //__BasicExample_OpenGLWidget_H__
#endif //__BasicExample_OpenGLWidget_H__

View File

@ -50,21 +50,26 @@ void createSphereInVolume(SimpleVolume<MaterialDensityPair44>& 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<MaterialDensityPair44>::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<MaterialDensityPair44>::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);
}
}
}

View File

@ -248,4 +248,4 @@ void OpenGLWidget::setupProjectionMatrix(void)
float aspect = static_cast<float>(width()) / static_cast<float>(height());
glOrtho(frustumSize*aspect, -frustumSize*aspect, frustumSize, -frustumSize, 1.0, 5000);
}
}

View File

@ -80,4 +80,4 @@ class OpenGLWidget : public QGLWidget
unsigned int m_uVolumeDepthInRegions;
};
#endif //__PolyVox_OpenGLWidget_H__
#endif //__PolyVox_OpenGLWidget_H__

View File

@ -30,7 +30,7 @@ using namespace PolyVox;
void createSphereInVolume(LargeVolume<MaterialDensityPair44>& 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<int32_t>(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<MaterialDensityPair44>& 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<MaterialDensityPair44>::MaxDensity : VoxelTypeTraits<MaterialDensityPair44>::MinDensity));
volData.setVoxelAt(x,y,z, MaterialDensityPair44(uValue, uValue > 0 ? VoxelTypeTraits<MaterialDensityPair44>::maxDensity() : VoxelTypeTraits<MaterialDensityPair44>::minDensity()));
}
}
}
@ -57,8 +57,8 @@ void createSphereInVolume(LargeVolume<MaterialDensityPair44>& volData, float fRa
void createCubeInVolume(LargeVolume<MaterialDensityPair44>& volData, Vector3DInt32 lowerCorner, Vector3DInt32 upperCorner, uint8_t uValue)
{
int maxDen = VoxelTypeTraits<MaterialDensityPair44>::MaxDensity;
int minDen = VoxelTypeTraits<MaterialDensityPair44>::MinDensity;
int maxDen = VoxelTypeTraits<MaterialDensityPair44>::maxDensity();
int minDen = VoxelTypeTraits<MaterialDensityPair44>::minDensity();
//This three-level for loop iterates over every voxel between the specified corners
for (int z = lowerCorner.getZ(); z <= upperCorner.getZ(); z++)
{

View File

@ -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<MaterialDensityPair44>::MaxDensity);
createCubeInVolume(volData, Vector3DInt32(midPos-10, 1, midPos-10), Vector3DInt32(midPos+10, maxPos-1, midPos+10), VoxelTypeTraits<MaterialDensityPair44>::MaxDensity);
createCubeInVolume(volData, Vector3DInt32(midPos-10, midPos-10 ,1), Vector3DInt32(midPos+10, midPos+10, maxPos-1), VoxelTypeTraits<MaterialDensityPair44>::MaxDensity);
createCubeInVolume(volData, Vector3DInt32(1, midPos-10, midPos-10), Vector3DInt32(maxPos-1, midPos+10, midPos+10), VoxelTypeTraits<MaterialDensityPair44>::maxDensity());
createCubeInVolume(volData, Vector3DInt32(midPos-10, 1, midPos-10), Vector3DInt32(midPos+10, maxPos-1, midPos+10), VoxelTypeTraits<MaterialDensityPair44>::maxDensity());
createCubeInVolume(volData, Vector3DInt32(midPos-10, midPos-10 ,1), Vector3DInt32(midPos+10, midPos+10, maxPos-1), VoxelTypeTraits<MaterialDensityPair44>::maxDensity());
//Smooth part of the volume
RawVolume<MaterialDensityPair44> tempVolume(PolyVox::Region(0,0,0,128, 128, 128));

View File

@ -132,4 +132,4 @@ void OpenGLWidget::mouseMoveEvent(QMouseEvent* event)
m_LastFrameMousePos = m_CurrentMousePos;
update();
}
}

View File

@ -64,4 +64,4 @@ private:
int m_yRotation;
};
#endif //__BasicExample_OpenGLWidget_H__
#endif //__BasicExample_OpenGLWidget_H__

View File

@ -50,7 +50,7 @@ void createPerlinVolumeSlow(LargeVolume<MaterialDensityPair44>& volData)
perlinVal += 1.0f;
perlinVal *= 0.5f;
perlinVal *= VoxelTypeTraits<MaterialDensityPair44>::MaxDensity;
perlinVal *= VoxelTypeTraits<MaterialDensityPair44>::maxDensity();
MaterialDensityPair44 voxel;
@ -60,12 +60,12 @@ void createPerlinVolumeSlow(LargeVolume<MaterialDensityPair44>& volData)
/*if(perlinVal < 0.0f)
{
voxel.setMaterial(245);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::MaxDensity);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::maxDensity());
}
else
{
voxel.setMaterial(0);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::MinDensity);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::minDensity());
}*/
volData.setVoxelAt(x, y, z, voxel);
@ -105,12 +105,12 @@ void createPerlinVolumeSlow(LargeVolume<MaterialDensityPair44>& volData)
if(perlinVal < 0.0f)
{
voxel.setMaterial(245);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::MaxDensity);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::maxDensity());
}
else
{
voxel.setMaterial(0);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::MinDensity);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::minDensity());
}
volData.setVoxelAt(x, y, z, voxel);
@ -143,12 +143,12 @@ void createPerlinTerrain(LargeVolume<MaterialDensityPair44>& volData)
if(z < perlinVal)
{
voxel.setMaterial(245);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::MaxDensity);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::maxDensity());
}
else
{
voxel.setMaterial(0);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::MinDensity);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::minDensity());
}
volData.setVoxelAt(x, y, z, voxel);
@ -181,7 +181,7 @@ void createSphereInVolume(LargeVolume<MaterialDensityPair44>& volData, Vector3DF
if(fDistToCenter <= fRadius)
{
//Our new density value
uint8_t uDensity = VoxelTypeTraits<MaterialDensityPair44>::MaxDensity;
uint8_t uDensity = VoxelTypeTraits<MaterialDensityPair44>::maxDensity();
//Get the old voxel
MaterialDensityPair44 voxel = volData.getVoxelAt(x,y,z);
@ -219,17 +219,17 @@ void load(const ConstVolumeProxy<MaterialDensityPair44>& volume, const PolyVox::
if((x-xpos)*(x-xpos) + (z-zpos)*(z-zpos) < 200) {
// tunnel
voxel.setMaterial(0);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::MinDensity);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::minDensity());
} else {
// solid
voxel.setMaterial(245);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::MaxDensity);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::maxDensity());
}
}
else
{
voxel.setMaterial(0);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::MinDensity);
voxel.setDensity(VoxelTypeTraits<MaterialDensityPair44>::minDensity());
}
volume.setVoxelAt(x, y, z, voxel);

View File

@ -183,4 +183,4 @@ void OpenGLWidget::mouseMoveEvent(QMouseEvent* event)
m_LastFrameMousePos = m_CurrentMousePos;
update();
}
}

View File

@ -71,4 +71,4 @@ private:
int m_yRotation;
};
#endif //__BasicExample_OpenGLWidget_H__
#endif //__BasicExample_OpenGLWidget_H__

View File

@ -35,7 +35,7 @@ freely, subject to the following restrictions:
//Use the PolyVox namespace
using namespace PolyVox;
void createSphereInVolume(SimpleVolume<Density8>& volData, float fRadius)
void createSphereInVolume(SimpleVolume<uint8_t>& 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<Density8>& volData, float fRadius)
if(fDistToCenter <= fRadius)
{
//Our new density value
//uint8_t uDensity = Density8::getMaxDensity();
uint8_t uDensity = VoxelTypeTraits<Density8>::MaxDensity;
//uint8_t uDensity = Density8::getmaxDensity()();
uint8_t uDensity = VoxelTypeTraits<Density8>::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<Density8> volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(63, 63, 63)));
SimpleVolume<uint8_t> 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<SimpleVolume, Density8>(volData, volData.getEnclosingRegion());
//smoothRegion<SimpleVolume, Density8>(volData, volData.getEnclosingRegion());
RawVolume<Density8> volDataLowLOD(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(15, 31, 31)));
RawVolume<uint8_t> volDataLowLOD(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(15, 31, 31)));
VolumeResampler<SimpleVolume, RawVolume, Density8> volumeResampler(&volData, PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 63, 63)), &volDataLowLOD, volDataLowLOD.getEnclosingRegion());
VolumeResampler<SimpleVolume, RawVolume, uint8_t> volumeResampler(&volData, PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 63, 63)), &volDataLowLOD, volDataLowLOD.getEnclosingRegion());
volumeResampler.execute();
//Extract the surface
SurfaceMesh<PositionMaterialNormal> meshLowLOD;
SurfaceExtractor<RawVolume, Density8 > surfaceExtractor(&volDataLowLOD, volDataLowLOD.getEnclosingRegion(), &meshLowLOD);
SurfaceExtractor<RawVolume, uint8_t > surfaceExtractor(&volDataLowLOD, volDataLowLOD.getEnclosingRegion(), &meshLowLOD);
surfaceExtractor.execute();
meshLowLOD.scaleVertices(/*2.0f*/63.0f / 31.0f);
//Extract the surface
SurfaceMesh<PositionMaterialNormal> meshHighLOD;
SurfaceExtractor<SimpleVolume, Density8 > surfaceExtractorHigh(&volData, PolyVox::Region(Vector3DInt32(30,0,0), Vector3DInt32(63, 63, 63)), &meshHighLOD);
SurfaceExtractor<SimpleVolume, uint8_t > surfaceExtractorHigh(&volData, PolyVox::Region(Vector3DInt32(30,0,0), Vector3DInt32(63, 63, 63)), &meshHighLOD);
surfaceExtractorHigh.execute();
meshHighLOD.translateVertices(Vector3DFloat(30, 0, 0));

View File

@ -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

View File

@ -28,6 +28,7 @@ freely, subject to the following restrictions:
#include "PolyVoxImpl/TypeDef.h"
#include "PolyVoxCore/Array.h"
#include "PolyVoxCore/Voxel.h"
#include <list>
#include <stdexcept> //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<typename> class VolumeType, typename VoxelType>
bool aStarDefaultVoxelValidator(const VolumeType<VoxelType>* volData, const Vector3DInt32& v3dPos);
@ -71,7 +72,7 @@ namespace PolyVox
float fHBias = 1.0,
uint32_t uMaxNoOfNodes = 10000,
Connectivity connectivity = TwentySixConnected,
polyvox_function<bool (const VolumeType<VoxelType>*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator<VolumeType, VoxelType>,
polyvox_function<bool (const VolumeType<VoxelType>*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator,
polyvox_function<void (float)> funcProgressCallback = 0
)
:volume(volData)

View File

@ -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;
}
}
}

View File

@ -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 <algorithm>
namespace PolyVox
@ -39,12 +45,19 @@ namespace PolyVox
class AmbientOcclusionCalculator
{
public:
AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement);
AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, polyvox_function<bool(const VoxelType& voxel)> 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<VoxelType>::Sampler& sampler);
#else
bool raycastCallback(const typename VolumeType<VoxelType>::Sampler& sampler);
#endif
Region m_region;
typename VolumeType<VoxelType>::Sampler m_sampVolume;
VolumeType<VoxelType>* m_volInput;
@ -56,6 +69,8 @@ namespace PolyVox
uint16_t mRandomUnitVectorIndex;
uint16_t mRandomVectorIndex;
uint16_t mIndexIncreament;
polyvox_function<bool(const VoxelType& voxel)> m_funcIsTransparent;
};
}

View File

@ -24,7 +24,7 @@ freely, subject to the following restrictions:
namespace PolyVox
{
template< template<typename> class VolumeType, typename VoxelType>
AmbientOcclusionCalculator<VolumeType, VoxelType>::AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement)
AmbientOcclusionCalculator<VolumeType, VoxelType>::AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, polyvox_function<bool(const VoxelType& voxel)> 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<VolumeType, VoxelType> raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult);
Raycast<VolumeType, VoxelType> raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult, polyvox_bind(&PolyVox::AmbientOcclusionCalculator<VolumeType,VoxelType>::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
}
}
}
}
template< template<typename> class VolumeType, typename VoxelType>
#if defined(_MSC_VER)
bool AmbientOcclusionCalculator<VolumeType, VoxelType>::raycastCallback(const typename SimpleVolume<VoxelType>::Sampler& sampler)
#else
bool AmbientOcclusionCalculator<VolumeType, VoxelType>::raycastCallback(const typename VolumeType<VoxelType>::Sampler& sampler)
#endif
{
VoxelType voxel = sampler.getVoxel();
return m_funcIsTransparent(voxel);
}
}

View File

@ -74,4 +74,4 @@ namespace PolyVox
};
}//namespace PolyVox
#endif //__PolyVox_ArraySizes_H__
#endif //__PolyVox_ArraySizes_H__

View File

@ -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);

View File

@ -41,23 +41,9 @@ namespace PolyVox
template <typename VoxelType>
template <typename DerivedVolumeType>
int32_t BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getPosX(void) const
Vector3DInt32 BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getPosition(void) const
{
return mXPosInVolume;
}
template <typename VoxelType>
template <typename DerivedVolumeType>
int32_t BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getPosY(void) const
{
return mYPosInVolume;
}
template <typename VoxelType>
template <typename DerivedVolumeType>
int32_t BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getPosZ(void) const
{
return mZPosInVolume;
return Vector3DInt32(mXPosInVolume, mYPosInVolume, mZPosInVolume);
}
template <typename VoxelType>

View File

@ -76,4 +76,4 @@ namespace PolyVox
};
}
#endif //__PolyVox_ConstVolumeProxy_H__
#endif //__PolyVox_ConstVolumeProxy_H__

View File

@ -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;
}
}
}

View File

@ -48,9 +48,9 @@ namespace PolyVox
float regY = static_cast<float>(y - m_regSizeInVoxels.getLowerCorner().getY());
float regZ = static_cast<float>(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<float>(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<float>(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<float>(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);
}
}
}

View File

@ -31,6 +31,9 @@ freely, subject to the following restrictions:
#include <cassert>
#include <limits>
#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 <typename Type>
class Density : public Voxel<Type, uint8_t>
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<DensityType>::max)(); }
//static DensityType getMinDensity() throw() { return (std::numeric_limits<DensityType>::min)(); }
//static DensityType getmaxDensity()() throw() { return (std::numeric_limits<DensityType>::max)(); }
//static DensityType getminDensity()() throw() { return (std::numeric_limits<DensityType>::min)(); }
static DensityType getThreshold() throw() { return (std::numeric_limits<DensityType>::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<int8_t> DensityI8;
typedef Density<uint8_t> DensityU8;
typedef Density<int16_t> DensityI16;
typedef Density<uint16_t> DensityU16;
typedef Density<float> DensityFloat;
typedef Density<double> 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<uint8_t> Density8;
typedef Density<uint16_t> 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<int8_t> >
template<>
class VoxelTypeTraits< Density8 >
{
public:
const static int8_t MinDensity;
const static int8_t MaxDensity;
};*/
/*template<>
class VoxelTypeTraits< Density<uint8_t> >
{
public:
const static uint8_t MinDensity;
const static uint8_t MaxDensity;
};*/
/*template<>
class VoxelTypeTraits< Density<int16_t> >
{
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<Density8::DensityType>::min(); }
static Density8::DensityType maxDensity() { return std::numeric_limits<Density8::DensityType>::max(); }
};
template<>
class VoxelTypeTraits< Density<uint16_t> >
{
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<float> >
{
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<double> >
{
public:
const static double MinDensity;
const static double MaxDensity;
};*/
typename VoxelTypeTraits<Density8>::DensityType convertToDensity(Density8 voxel);
}
#endif //__PolyVox_Density_H__

View File

@ -47,9 +47,9 @@ namespace PolyVox
template< template<typename> class VolumeType, typename VoxelType>
Vector3DFloat computeDecimatedCentralDifferenceGradient(const typename VolumeType<VoxelType>::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<typename> class VolumeType, typename VoxelType>
Vector3DFloat computeSmoothCentralDifferenceGradient(typename VolumeType<VoxelType>::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);

View File

@ -32,7 +32,7 @@ namespace PolyVox
template <typename IteratorType>
bool IteratorController<IteratorType>::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())
{

View File

@ -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

View File

@ -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 <typename VoxelType>
void LargeVolume<VoxelType>::resize(const Region& regValidRegion, uint16_t uBlockSideLength)
void LargeVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
{
//Debug mode validation
assert(uBlockSideLength > 0);

View File

@ -54,24 +54,6 @@ namespace PolyVox
return *this;
}
template <typename VoxelType>
int32_t LargeVolume<VoxelType>::Sampler::getPosX(void) const
{
return this->mXPosInVolume;
}
template <typename VoxelType>
int32_t LargeVolume<VoxelType>::Sampler::getPosY(void) const
{
return this->mYPosInVolume;
}
template <typename VoxelType>
int32_t LargeVolume<VoxelType>::Sampler::getPosZ(void) const
{
return this->mZPosInVolume;
}
template <typename VoxelType>
VoxelType LargeVolume<VoxelType>::Sampler::getSubSampledVoxel(uint8_t uLevel) const
{
@ -321,7 +303,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType LargeVolume<VoxelType>::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
#undef BORDER_HIGH

View File

@ -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
#endif

View File

@ -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;

View File

@ -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 <typename Type>
class Material : public Voxel<uint8_t, Type>
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<uint8_t> Material8;
typedef Material<uint16_t> Material16;
typedef Material<uint32_t> 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__

View File

@ -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 <typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits>
class MaterialDensityPair : public Voxel<Type, Type>
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<uint8_t, 4, 4> MaterialDensityPair44;
typedef MaterialDensityPair<uint16_t, 8, 8> MaterialDensityPair88;
/*template<typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits>
class VoxelTypeTraits< MaterialDensityPair<Type, NoOfDensityBits, NoOfMaterialBits> >
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
#include "PolyVoxCore/SurfaceExtractor.h"
namespace PolyVox
{
template<>
typename VoxelTypeTraits<MaterialDensityPair44>::DensityType convertToDensity(MaterialDensityPair44 voxel);
template<>
typename VoxelTypeTraits<MaterialDensityPair88>::DensityType convertToDensity(MaterialDensityPair88 voxel);
template<>
typename VoxelTypeTraits<MaterialDensityPair44>::MaterialType convertToMaterial(MaterialDensityPair44 voxel);
template<>
typename VoxelTypeTraits<MaterialDensityPair88>::MaterialType convertToMaterial(MaterialDensityPair88 voxel);
}
#endif

View File

@ -28,10 +28,13 @@ freely, subject to the following restrictions:
namespace PolyVox
{
//---------- Array ----------
////////////////////////////////////////////////////////////////////////////////
// Array
////////////////////////////////////////////////////////////////////////////////
template<uint32_t dimensions, typename ElementType> 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 <typename VoxelType> class Block;
//---------- LargeVolume ----------
template <typename VoxelType> class LargeVolume;
//---------------------------------
template <typename Type> class Density;
typedef Density<uint8_t> Density8;
template <typename Type> class Material;
typedef Material<uint8_t> Material8;
typedef Material<uint16_t> Material16;
typedef Material<uint32_t> Material32;
template <typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits> class MaterialDensityPair;
typedef MaterialDensityPair<uint8_t, 4, 4> MaterialDensityPair44;
template <typename VertexType> class SurfaceMesh;
class Region;
class PositionMaterial;
class PositionMaterialNormal;
////////////////////////////////////////////////////////////////////////////////
// CubicSurfaceExtractor
////////////////////////////////////////////////////////////////////////////////
template< template<typename> class VolumeType, typename VoxelType> class CubicSurfaceExtractor;
////////////////////////////////////////////////////////////////////////////////
// Density
////////////////////////////////////////////////////////////////////////////////
template <typename Type> class Density;
typedef Density<int8_t> DensityI8;
typedef Density<uint8_t> DensityU8;
typedef Density<int16_t> DensityI16;
typedef Density<uint16_t> DensityU16;
typedef Density<float> DensityFloat;
typedef Density<double> DensityDouble;
typedef DensityU8 Density8; //Backwards compatibility
typedef DensityU16 Density16; //Backwards compatibility
////////////////////////////////////////////////////////////////////////////////
// LargeVolume
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType> class LargeVolume;
////////////////////////////////////////////////////////////////////////////////
// Material
////////////////////////////////////////////////////////////////////////////////
template <typename Type> class Material;
typedef Material<uint8_t> MaterialU8;
typedef Material<uint16_t> MaterialU16;
typedef Material<uint32_t> MaterialU32;
typedef MaterialU8 Material8;
typedef MaterialU16 Material16;
typedef MaterialU32 Material32;
////////////////////////////////////////////////////////////////////////////////
// MaterialDensityPair
////////////////////////////////////////////////////////////////////////////////
template <typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits> class MaterialDensityPair;
typedef MaterialDensityPair<uint8_t, 4, 4> MaterialDensityPair44;
typedef MaterialDensityPair<uint16_t, 8, 8> MaterialDensityPair88;
////////////////////////////////////////////////////////////////////////////////
// PositionMaterial
////////////////////////////////////////////////////////////////////////////////
class PositionMaterial;
////////////////////////////////////////////////////////////////////////////////
// PositionMaterialNormal
////////////////////////////////////////////////////////////////////////////////
class PositionMaterialNormal;
////////////////////////////////////////////////////////////////////////////////
// RawVolume
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType> class RawVolume;
////////////////////////////////////////////////////////////////////////////////
// Region
////////////////////////////////////////////////////////////////////////////////
class Region;
////////////////////////////////////////////////////////////////////////////////
// SurfaceExtractor
////////////////////////////////////////////////////////////////////////////////
template< template<typename> class VolumeType, typename VoxelType> class SurfaceExtractor;
//---------- Vector ----------
////////////////////////////////////////////////////////////////////////////////
// SurfaceMesh
////////////////////////////////////////////////////////////////////////////////
template <typename VertexType> class SurfaceMesh;
////////////////////////////////////////////////////////////////////////////////
// Vector
////////////////////////////////////////////////////////////////////////////////
template <uint32_t Size, typename Type> 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 <typename VoxelType> class Sampler;
}
#endif

View File

@ -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<typename Type>
const typename Type::DensityType VoxelTypeTraits<Type>::MinDensity = 0;
template<typename Type>
const typename Type::DensityType VoxelTypeTraits<Type>::MaxDensity = 0;
}
{
}
#endif //__PolyVox_PrimitiveVoxelTypes_H__

View File

@ -59,9 +59,6 @@ namespace PolyVox
Sampler(RawVolume<VoxelType>* 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;

View File

@ -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 <typename VoxelType>
void RawVolume<VoxelType>::resize(const Region& regValidRegion)
void RawVolume<VoxelType>::initialise(const Region& regValidRegion)
{
this->m_regValidRegion = regValidRegion;

View File

@ -45,24 +45,6 @@ namespace PolyVox
{
}
template <typename VoxelType>
int32_t RawVolume<VoxelType>::Sampler::getPosX(void) const
{
return this->mXPosInVolume;
}
template <typename VoxelType>
int32_t RawVolume<VoxelType>::Sampler::getPosY(void) const
{
return this->mYPosInVolume;
}
template <typename VoxelType>
int32_t RawVolume<VoxelType>::Sampler::getPosZ(void) const
{
return this->mZPosInVolume;
}
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::getVoxel(void) const
{
@ -224,7 +206,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::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
#undef BORDER_HIGHZ

View File

@ -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.
///
/// <b>Important Note:</b> 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<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result);
Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, RaycastResult& result, polyvox_function<bool(const typename VolumeType<VoxelType>::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<bool(const typename VolumeType<VoxelType>::Sampler& position)> m_funcIsPassable;
void doRaycast(float x1, float y1, float z1, float x2, float y2, float z2);
VolumeType<VoxelType>* m_volData;
typename VolumeType<VoxelType>::Sampler m_sampVolume;
Vector3DFloat m_v3dStart;
Vector3DFloat m_v3dDirection;
Vector3DFloat m_v3dDirectionAndLength;
float m_fMaxDistance;
};
}
#include "PolyVoxCore/Raycast.inl"
#endif //__PolyVox_Raycast_H__
#endif //__PolyVox_Raycast_H__

View File

@ -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<typename> class VolumeType, typename VoxelType>
Raycast<VolumeType, VoxelType>::Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result)
Raycast<VolumeType, VoxelType>::Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, RaycastResult& result, polyvox_function<bool(const typename VolumeType<VoxelType>::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<typename> class VolumeType, typename VoxelType>
void Raycast<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirection)
void Raycast<VolumeType, VoxelType>::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);
}
}
}

View File

@ -33,12 +33,12 @@ namespace PolyVox
{
public:
///Constructor
RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function<bool(const Vector3DInt32& position)> funcCallback);
RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, polyvox_function<bool(const Vector3DInt32& position)> 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<VoxelType>::Sampler m_sampVolume;
Vector3DFloat m_v3dStart;
Vector3DFloat m_v3dDirection;
Vector3DFloat m_v3dDirectionAndLength;
float m_fMaxDistance;
};
}

View File

@ -24,11 +24,11 @@ freely, subject to the following restrictions:
namespace PolyVox
{
template< template<typename> class VolumeType, typename VoxelType>
RaycastWithCallback<VolumeType, VoxelType>::RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function<bool(const Vector3DInt32& position)> funcCallback)
RaycastWithCallback<VolumeType, VoxelType>::RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, polyvox_function<bool(const Vector3DInt32& position)> 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<typename> class VolumeType, typename VoxelType>
void RaycastWithCallback<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirection)
void RaycastWithCallback<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirectionAndLength)
{
m_v3dDirection = v3dDirection;
m_v3dDirectionAndLength = v3dDirectionAndLength;
}
template< template<typename> 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());

View File

@ -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

View File

@ -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

View File

@ -57,7 +57,7 @@ namespace PolyVox
:BaseVolume<VoxelType>(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 <typename VoxelType>
void SimpleVolume<VoxelType>::resize(const Region& regValidRegion, uint16_t uBlockSideLength)
void SimpleVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
{
//Debug mode validation
assert(uBlockSideLength >= 8);

View File

@ -54,24 +54,6 @@ namespace PolyVox
return *this;
}
template <typename VoxelType>
int32_t SimpleVolume<VoxelType>::Sampler::getPosX(void) const
{
return this->mXPosInVolume;
}
template <typename VoxelType>
int32_t SimpleVolume<VoxelType>::Sampler::getPosY(void) const
{
return this->mYPosInVolume;
}
template <typename VoxelType>
int32_t SimpleVolume<VoxelType>::Sampler::getPosZ(void) const
{
return this->mZPosInVolume;
}
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::Sampler::getSubSampledVoxel(uint8_t uLevel) const
{
@ -329,7 +311,7 @@ namespace PolyVox
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::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);
}

View File

@ -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

View File

@ -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 VoxelType>
typename VoxelTypeTraits<VoxelType>::MaterialType convertToMaterial(VoxelType voxel)
{
return 1;
}
template< template<typename> class VolumeType, typename VoxelType>
class SurfaceExtractor
{
public:
SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result);
SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelTypeTraits<VoxelType>::DensityType tThreshold = (VoxelTypeTraits<VoxelType>::minDensity() + VoxelTypeTraits<VoxelType>::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<float>(volIter.peekVoxel1nx0py0pz().getDensity());
float voxel1px = static_cast<float>(volIter.peekVoxel1px0py0pz().getDensity());
float voxel1nx = static_cast<float>(convertToDensity(volIter.peekVoxel1nx0py0pz()));
float voxel1px = static_cast<float>(convertToDensity(volIter.peekVoxel1px0py0pz()));
float voxel1ny = static_cast<float>(volIter.peekVoxel0px1ny0pz().getDensity());
float voxel1py = static_cast<float>(volIter.peekVoxel0px1py0pz().getDensity());
float voxel1ny = static_cast<float>(convertToDensity(volIter.peekVoxel0px1ny0pz()));
float voxel1py = static_cast<float>(convertToDensity(volIter.peekVoxel0px1py0pz()));
float voxel1nz = static_cast<float>(volIter.peekVoxel0px0py1nz().getDensity());
float voxel1pz = static_cast<float>(volIter.peekVoxel0px0py1pz().getDensity());
float voxel1nz = static_cast<float>(convertToDensity(volIter.peekVoxel0px0py1nz()));
float voxel1pz = static_cast<float>(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<float>(volIter.peekVoxel1nx1ny1nz().getDensity());
const float pVoxel1nx1ny0pz = static_cast<float>(volIter.peekVoxel1nx1ny0pz().getDensity());
const float pVoxel1nx1ny1pz = static_cast<float>(volIter.peekVoxel1nx1ny1pz().getDensity());
const float pVoxel1nx0py1nz = static_cast<float>(volIter.peekVoxel1nx0py1nz().getDensity());
const float pVoxel1nx0py0pz = static_cast<float>(volIter.peekVoxel1nx0py0pz().getDensity());
const float pVoxel1nx0py1pz = static_cast<float>(volIter.peekVoxel1nx0py1pz().getDensity());
const float pVoxel1nx1py1nz = static_cast<float>(volIter.peekVoxel1nx1py1nz().getDensity());
const float pVoxel1nx1py0pz = static_cast<float>(volIter.peekVoxel1nx1py0pz().getDensity());
const float pVoxel1nx1py1pz = static_cast<float>(volIter.peekVoxel1nx1py1pz().getDensity());
const float pVoxel1nx1ny1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1ny1nz()));
const float pVoxel1nx1ny0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1ny0pz()));
const float pVoxel1nx1ny1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1ny1pz()));
const float pVoxel1nx0py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx0py1nz()));
const float pVoxel1nx0py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx0py0pz()));
const float pVoxel1nx0py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx0py1pz()));
const float pVoxel1nx1py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1py1nz()));
const float pVoxel1nx1py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1py0pz()));
const float pVoxel1nx1py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1py1pz()));
const float pVoxel0px1ny1nz = static_cast<float>(volIter.peekVoxel0px1ny1nz().getDensity());
const float pVoxel0px1ny0pz = static_cast<float>(volIter.peekVoxel0px1ny0pz().getDensity());
const float pVoxel0px1ny1pz = static_cast<float>(volIter.peekVoxel0px1ny1pz().getDensity());
const float pVoxel0px0py1nz = static_cast<float>(volIter.peekVoxel0px0py1nz().getDensity());
//const float pVoxel0px0py0pz = static_cast<float>(volIter.peekVoxel0px0py0pz().getDensity());
const float pVoxel0px0py1pz = static_cast<float>(volIter.peekVoxel0px0py1pz().getDensity());
const float pVoxel0px1py1nz = static_cast<float>(volIter.peekVoxel0px1py1nz().getDensity());
const float pVoxel0px1py0pz = static_cast<float>(volIter.peekVoxel0px1py0pz().getDensity());
const float pVoxel0px1py1pz = static_cast<float>(volIter.peekVoxel0px1py1pz().getDensity());
const float pVoxel0px1ny1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1ny1nz()));
const float pVoxel0px1ny0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1ny0pz()));
const float pVoxel0px1ny1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1ny1pz()));
const float pVoxel0px0py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px0py1nz()));
//const float pVoxel0px0py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px0py0pz()));
const float pVoxel0px0py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px0py1pz()));
const float pVoxel0px1py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1py1nz()));
const float pVoxel0px1py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1py0pz()));
const float pVoxel0px1py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1py1pz()));
const float pVoxel1px1ny1nz = static_cast<float>(volIter.peekVoxel1px1ny1nz().getDensity());
const float pVoxel1px1ny0pz = static_cast<float>(volIter.peekVoxel1px1ny0pz().getDensity());
const float pVoxel1px1ny1pz = static_cast<float>(volIter.peekVoxel1px1ny1pz().getDensity());
const float pVoxel1px0py1nz = static_cast<float>(volIter.peekVoxel1px0py1nz().getDensity());
const float pVoxel1px0py0pz = static_cast<float>(volIter.peekVoxel1px0py0pz().getDensity());
const float pVoxel1px0py1pz = static_cast<float>(volIter.peekVoxel1px0py1pz().getDensity());
const float pVoxel1px1py1nz = static_cast<float>(volIter.peekVoxel1px1py1nz().getDensity());
const float pVoxel1px1py0pz = static_cast<float>(volIter.peekVoxel1px1py0pz().getDensity());
const float pVoxel1px1py1pz = static_cast<float>(volIter.peekVoxel1px1py1pz().getDensity());
const float pVoxel1px1ny1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1ny1nz()));
const float pVoxel1px1ny0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1ny0pz()));
const float pVoxel1px1ny1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1ny1pz()));
const float pVoxel1px0py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px0py1nz()));
const float pVoxel1px0py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px0py0pz()));
const float pVoxel1px0py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px0py1pz()));
const float pVoxel1px1py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1py1nz()));
const float pVoxel1px1py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1py0pz()));
const float pVoxel1px1py1pz = static_cast<float>(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<VoxelType>::DensityType m_tThreshold;
};
}

View File

@ -24,11 +24,12 @@ freely, subject to the following restrictions:
namespace PolyVox
{
template< template<typename> class VolumeType, typename VoxelType>
SurfaceExtractor<VolumeType, VoxelType>::SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result)
SurfaceExtractor<VolumeType, VoxelType>::SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelTypeTraits<VoxelType>::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<float>(v100.getDensity() - VoxelType::getMinDensity()) / static_cast<float>(VoxelType::getMaxDensity() - VoxelType::getMinDensity());
float fInterp = static_cast<float>(VoxelType::getThreshold() - v000.getDensity()) / static_cast<float>(v100.getDensity() - v000.getDensity());
//fInterp = 0.5f;
float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v100) - convertToDensity(v000));
const Vector3DFloat v3dPosition(static_cast<float>(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()) + fInterp, static_cast<float>(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast<float>(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<float>(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<float>(VoxelType::getThreshold() - v000.getDensity()) / static_cast<float>(v010.getDensity() - v000.getDensity());
//fInterp = 0.5f;
float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v010) - convertToDensity(v000));
const Vector3DFloat v3dPosition(static_cast<float>(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast<float>(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()) + fInterp, static_cast<float>(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<float>(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<float>(VoxelType::getThreshold() - v000.getDensity()) / static_cast<float>(v001.getDensity() - v000.getDensity());
//fInterp = 0.5f;
float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v001) - convertToDensity(v000));
const Vector3DFloat v3dPosition(static_cast<float>(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast<float>(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast<float>(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<float>(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

View File

@ -100,6 +100,11 @@ namespace PolyVox
template <typename VertexType>
void SurfaceMesh<VertexType>::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 <typename VertexType>
void SurfaceMesh<VertexType>::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);
}
}
}
}

View File

@ -21,6 +21,8 @@ freely, subject to the following restrictions:
distribution.
*******************************************************************************/
#include "PolyVoxImpl/Utility.h"
namespace PolyVox
{
template< template<typename> class SrcVolumeType, template<typename> 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<VoxelType>::DensityType voxel000Den = convertToDensity(voxel000);
typename VoxelTypeTraits<VoxelType>::DensityType voxel001Den = convertToDensity(voxel001);
typename VoxelTypeTraits<VoxelType>::DensityType voxel010Den = convertToDensity(voxel010);
typename VoxelTypeTraits<VoxelType>::DensityType voxel011Den = convertToDensity(voxel011);
typename VoxelTypeTraits<VoxelType>::DensityType voxel100Den = convertToDensity(voxel100);
typename VoxelTypeTraits<VoxelType>::DensityType voxel101Den = convertToDensity(voxel101);
typename VoxelTypeTraits<VoxelType>::DensityType voxel110Den = convertToDensity(voxel110);
typename VoxelTypeTraits<VoxelType>::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<float>(voxel000Den,voxel100Den,voxel010Den,voxel110Den,voxel001Den,voxel101Den,voxel011Den,voxel111Den,sx,sy,sz);
typename VoxelTypeTraits<VoxelType>::DensityType uInterpolatedDensity = trilinearlyInterpolate<float>(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);
}

View File

@ -30,37 +30,15 @@ freely, subject to the following restrictions:
#include <limits>
namespace PolyVox
{
/// This class represents a voxel
////////////////////////////////////////////////////////////////////////////////
/// Detailed description...
////////////////////////////////////////////////////////////////////////////////
template <typename DenType, typename MatType>
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 VoxelType>
typename VoxelTypeTraits<VoxelType>::DensityType convertToDensity(VoxelType voxel)
{
return voxel;
}
}
#endif //__PolyVox_Voxel_H__

View File

@ -32,4 +32,4 @@ namespace PolyVox
float computeSmoothedVoxel(typename VolumeType<uint8_t>::Sampler& volIter);
}
#endif
#endif

View File

@ -221,4 +221,4 @@ namespace PolyVox
//bool operator<(const AllNodesContainer::iterator& lhs, const AllNodesContainer::iterator& rhs);
}
#endif //__PolyVox_AStarPathfinderImpl_H__
#endif //__PolyVox_AStarPathfinderImpl_H__

View File

@ -43,4 +43,4 @@ namespace PolyVox
std::copy(&pSizes[0],&pSizes[N-1],m_pSizes);
m_pSizes[N-1]=uSize;
}
}//namespace PolyVox
}//namespace PolyVox

View File

@ -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

View File

@ -85,4 +85,4 @@ namespace PolyVox
#include "PolyVoxImpl/SubArray.inl"
#endif //__PolyVox_SubArray_H__
#endif //__PolyVox_SubArray_H__

View File

@ -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 <boost/static_assert.hpp>
#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

View File

@ -64,4 +64,4 @@ namespace PolyVox
Vector3DInt32(+1, +1, -1),
Vector3DInt32(+1, +1, +1)
};
}
}

View File

@ -52,4 +52,4 @@ namespace PolyVox
{
return m_pSizes;
}
}
}

View File

@ -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 <cfloat> //Can't use <limits> as we need compile time constants.
namespace PolyVox
{
template<>
const int8_t VoxelTypeTraits< Density<int8_t> >::MinDensity = -127;
template<>
const int8_t VoxelTypeTraits< Density<int8_t> >::MaxDensity = 127;
template<>
const uint8_t VoxelTypeTraits< Density<uint8_t> >::MinDensity = 0;
template<>
const uint8_t VoxelTypeTraits< Density<uint8_t> >::MaxDensity = 255;
template<>
const int16_t VoxelTypeTraits< Density<int16_t> >::MinDensity = -32767;
template<>
const int16_t VoxelTypeTraits< Density<int16_t> >::MaxDensity = 32767;
template<>
const uint16_t VoxelTypeTraits< Density<uint16_t> >::MinDensity = 0;
template<>
const uint16_t VoxelTypeTraits< Density<uint16_t> >::MaxDensity = 65535;
template<>
const float VoxelTypeTraits< Density<float> >::MinDensity = FLT_MIN;
template<>
const float VoxelTypeTraits< Density<float> >::MaxDensity = FLT_MAX;
template<>
const double VoxelTypeTraits< Density<double> >::MinDensity = DBL_MIN;
template<>
const double VoxelTypeTraits< Density<double> >::MaxDensity = DBL_MAX;
}
/*******************************************************************************
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<Density8>::DensityType convertToDensity(Density8 voxel)
{
return voxel.getDensity();
}
}

View File

@ -26,4 +26,4 @@ freely, subject to the following restrictions:
namespace PolyVox
{
void (*logHandler)(std::string, int severity) = 0;
}
}

View File

@ -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 <set>
namespace PolyVox
{
class SurfaceVertex;
typedef std::set<SurfaceVertex>::iterator SurfaceVertexIterator;
typedef std::set<SurfaceVertex>::const_iterator SurfaceVertexConstIterator;
class SurfaceTriangle;
typedef std::set<SurfaceTriangle>::iterator SurfaceTriangleIterator;
typedef std::set<SurfaceTriangle>::const_iterator SurfaceTriangleConstIterator;
class SurfaceEdge;
typedef std::set<SurfaceEdge>::iterator SurfaceEdgeIterator;
typedef std::set<SurfaceEdge>::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<Material8>::DensityType convertToDensity(Material8 voxel)
//{
// return voxel.getDensity();
//}
}

View File

@ -25,13 +25,27 @@ freely, subject to the following restrictions:
namespace PolyVox
{
//template<typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits>
//const Type VoxelTypeTraits< MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> >::MinDensity = 0;
//template<typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits>
//const Type VoxelTypeTraits< Type >::MaxDensity = (0x01 << NoOfDensityBits) - 1;
template<>
const uint8_t VoxelTypeTraits< MaterialDensityPair44 >::MinDensity = 0;
typename VoxelTypeTraits<MaterialDensityPair44>::DensityType convertToDensity(MaterialDensityPair44 voxel)
{
return voxel.getDensity();
}
template<>
const uint8_t VoxelTypeTraits< MaterialDensityPair44 >::MaxDensity = 15;
}
typename VoxelTypeTraits<MaterialDensityPair88>::DensityType convertToDensity(MaterialDensityPair88 voxel)
{
return voxel.getDensity();
}
template<>
typename VoxelTypeTraits<MaterialDensityPair44>::MaterialType convertToMaterial(MaterialDensityPair44 voxel)
{
return voxel.getMaterial();
}
template<>
typename VoxelTypeTraits<MaterialDensityPair88>::MaterialType convertToMaterial(MaterialDensityPair88 voxel)
{
return voxel.getMaterial();
}
}

View File

@ -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, },

View File

@ -1052,4 +1052,4 @@ namespace PolyVox
Vector3DFloat(+0.862667f, +0.053377f, +0.652333f),
Vector3DFloat(-0.002289f, +0.568834f, -0.069185f)
};
}
}

View File

@ -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)

View File

@ -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 <sstream>
#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;
}
}

View File

@ -63,4 +63,4 @@ namespace PolyVox
sum /= 27.0f;
return sum;
}
}
}

View File

@ -13,4 +13,4 @@ namespace PolyVox
{
return x;
}
}
}

View File

@ -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)

View File

@ -31,40 +31,31 @@ freely, subject to the following restrictions:
using namespace PolyVox;
template< template<typename> class VolumeType, typename VoxelType>
bool testVoxelValidator(const VolumeType<VoxelType>* volData, const Vector3DInt32& v3dPos)
{
//Voxels are considered valid candidates for the path if they are inside the volume...
if(volData->getEnclosingRegion().containsPoint(v3dPos) == false)
{
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<Material8> 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<uint8_t> 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<Vector3DInt32> result;
//Create an AStarPathfinder
AStarPathfinderParams<RawVolume, Material8> params(&volData, Vector3DInt32(0,0,0), Vector3DInt32(15,15,15), &result);
AStarPathfinder<RawVolume, Material8> pathfinder(params);
AStarPathfinderParams<RawVolume, uint8_t> params(&volData, Vector3DInt32(0,0,0), Vector3DInt32(15,15,15), &result, 1.0f, 10000, TwentySixConnected, &testVoxelValidator<RawVolume, uint8_t>);
AStarPathfinder<RawVolume, uint8_t> pathfinder(params);
//Execute the pathfinder.
pathfinder.execute();

View File

@ -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 <QtTest>
using namespace PolyVox;
bool isVoxelTransparent(uint8_t voxel)
{
return voxel == 0;
}
void TestAmbientOcclusionGenerator::testExecute()
{
const int32_t g_uVolumeSideLength = 64;
//Create empty volume
SimpleVolume<Material8> volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1)));
SimpleVolume<uint8_t> 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<SimpleVolume, Material8> calculator(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 255);
AmbientOcclusionCalculator<SimpleVolume, uint8_t> calculator(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 255, isVoxelTransparent);
//Execute the calculator
calculator.execute();

View File

@ -63,24 +63,24 @@ void TestLowPassFilter::testExecute()
pass1.execute();
std::cout << "Input volume:" << std::endl;
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(0,0,0).getDensity()) << std::endl; // 32
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(1,1,1).getDensity()) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(2,2,2).getDensity()) << std::endl; // 3
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(3,3,3).getDensity()) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(4,4,4).getDensity()) << std::endl; // 32
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(5,5,5).getDensity()) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(6,6,6).getDensity()) << std::endl; // 32
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(7,7,7).getDensity()) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(convertToDensity(volData.getVoxelAt(0,0,0))) << std::endl; // 32
std::cout << "Voxel = " << static_cast<int>(convertToDensity(volData.getVoxelAt(1,1,1))) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(convertToDensity(volData.getVoxelAt(2,2,2))) << std::endl; // 3
std::cout << "Voxel = " << static_cast<int>(convertToDensity(volData.getVoxelAt(3,3,3))) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(convertToDensity(volData.getVoxelAt(4,4,4))) << std::endl; // 32
std::cout << "Voxel = " << static_cast<int>(convertToDensity(volData.getVoxelAt(5,5,5))) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(convertToDensity(volData.getVoxelAt(6,6,6))) << std::endl; // 32
std::cout << "Voxel = " << static_cast<int>(convertToDensity(volData.getVoxelAt(7,7,7))) << std::endl; // 0
std::cout << std::endl << "Output volume:" << std::endl;
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(0,0,0).getDensity()) << std::endl; // 4
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(1,1,1).getDensity()) << std::endl; // 21
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(2,2,2).getDensity()) << std::endl; // 10
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(3,3,3).getDensity()) << std::endl; // 21
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(4,4,4).getDensity()) << std::endl; // 10
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(5,5,5).getDensity()) << std::endl; // 21
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(6,6,6).getDensity()) << std::endl; // 10
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(7,7,7).getDensity()) << std::endl; // 4
std::cout << "Voxel = " << static_cast<int>(convertToDensity(resultVolume.getVoxelAt(0,0,0))) << std::endl; // 4
std::cout << "Voxel = " << static_cast<int>(convertToDensity(resultVolume.getVoxelAt(1,1,1))) << std::endl; // 21
std::cout << "Voxel = " << static_cast<int>(convertToDensity(resultVolume.getVoxelAt(2,2,2))) << std::endl; // 10
std::cout << "Voxel = " << static_cast<int>(convertToDensity(resultVolume.getVoxelAt(3,3,3))) << std::endl; // 21
std::cout << "Voxel = " << static_cast<int>(convertToDensity(resultVolume.getVoxelAt(4,4,4))) << std::endl; // 10
std::cout << "Voxel = " << static_cast<int>(convertToDensity(resultVolume.getVoxelAt(5,5,5))) << std::endl; // 21
std::cout << "Voxel = " << static_cast<int>(convertToDensity(resultVolume.getVoxelAt(6,6,6))) << std::endl; // 10
std::cout << "Voxel = " << static_cast<int>(convertToDensity(resultVolume.getVoxelAt(7,7,7))) << std::endl; // 4
}
QTEST_MAIN(TestLowPassFilter)

83
tests/TestRaycast.cpp Normal file
View File

@ -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 <QtTest>
using namespace PolyVox;
bool isPassableByRay(const SimpleVolume<int8_t>::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<int8_t> 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<SimpleVolume, int8_t> 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)

37
tests/TestRaycast.h Normal file
View File

@ -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 <QObject>
class TestRaycast: public QObject
{
Q_OBJECT
private slots:
void testExecute();
};
#endif

View File

@ -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 <QtTest>
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<typename VoxelType>
void writeDensityValueToVoxel(typename VoxelTypeTraits<VoxelType>::DensityType valueToWrite, VoxelType& voxel)
{
voxel = valueToWrite;
}
template<>
void writeDensityValueToVoxel(typename VoxelTypeTraits<Density8>::DensityType valueToWrite, Density8& voxel)
{
voxel.setDensity(valueToWrite);
}
template<>
void writeDensityValueToVoxel(typename VoxelTypeTraits<MaterialDensityPair88>::DensityType valueToWrite, MaterialDensityPair88& voxel)
{
voxel.setDensity(valueToWrite);
}
template<typename VoxelType>
void writeMaterialValueToVoxel(typename VoxelTypeTraits<VoxelType>::MaterialType valueToWrite, VoxelType& voxel)
{
//Most types don't have a material
return;
}
template<>
void writeMaterialValueToVoxel(typename VoxelTypeTraits<MaterialDensityPair88>::MaterialType valueToWrite, MaterialDensityPair88& voxel)
{
voxel.setMaterial(valueToWrite);
}
// Runs the surface extractor for a given type.
template <typename VoxelType>
void testForType(SurfaceMesh<PositionMaterialNormal>& result)
{
const int32_t uVolumeSideLength = 32;
//Create empty volume
SimpleVolume<VoxelType> 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<VoxelType>(x + y + z, voxelValue);
//Two different materials in two halves of the volume
writeMaterialValueToVoxel<VoxelType>(z > uVolumeSideLength / 2 ? 42 : 79, voxelValue);
volData.setVoxelAt(x, y, z, voxelValue);
}
}
}
SurfaceExtractor<SimpleVolume, VoxelType > 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<PositionMaterialNormal> mesh;
testForType<int8_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<uint8_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<int16_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<uint16_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<int32_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<uint32_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<float>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<double>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<Density8>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<MaterialDensityPair88>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fExpectedMaterial);
}
QTEST_MAIN(TestSurfaceExtractor)

View File

@ -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 <QObject>
class TestSurfaceExtractor: public QObject
{
Q_OBJECT
private slots:
void testExecute();
};
#endif

View File

@ -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<Density8>::minDensity(), Density8::DensityType(0));
QCOMPARE(VoxelTypeTraits<Density8>::maxDensity(), Density8::DensityType(255));
QCOMPARE(VoxelTypeTraits<DensityI8>::minDensity(), DensityI8::DensityType(-127));
QCOMPARE(VoxelTypeTraits<DensityI8>::maxDensity(), DensityI8::DensityType(127));
QCOMPARE(VoxelTypeTraits<Density8>::MaxDensity, static_cast<uint8_t>(0));
QCOMPARE(VoxelTypeTraits<Density8>::MaxDensity, static_cast<uint8_t>(255));
QCOMPARE(VoxelTypeTraits<DensityU8>::minDensity(), DensityU8::DensityType(0));
QCOMPARE(VoxelTypeTraits<DensityU8>::maxDensity(), DensityU8::DensityType(255));
fValue = VoxelTypeTraits<DensityFloat>::MinDensity;
QCOMPARE(fValue, FLT_MIN);
fValue = VoxelTypeTraits<DensityFloat>::MaxDensity;
QCOMPARE(fValue, FLT_MAX);
QCOMPARE(VoxelTypeTraits<Density16>::minDensity(), Density16::DensityType(0));
QCOMPARE(VoxelTypeTraits<Density16>::maxDensity(), Density16::DensityType(65535));
/*iValue = VoxelTypeTraits<Material8>::MinDensity;
QCOMPARE(VoxelTypeTraits<DensityI16>::minDensity(), DensityI16::DensityType(-32767));
QCOMPARE(VoxelTypeTraits<DensityI16>::maxDensity(), DensityI16::DensityType(32767));
QCOMPARE(VoxelTypeTraits<DensityU16>::minDensity(), DensityU16::DensityType(0));
QCOMPARE(VoxelTypeTraits<DensityU16>::maxDensity(), DensityU16::DensityType(65535));
QCOMPARE(VoxelTypeTraits<DensityFloat>::minDensity(), -FLT_MAX);
QCOMPARE(VoxelTypeTraits<DensityFloat>::maxDensity(), FLT_MAX);
QCOMPARE(VoxelTypeTraits<DensityDouble>::minDensity(), -DBL_MAX);
QCOMPARE(VoxelTypeTraits<DensityDouble>::maxDensity(), DBL_MAX);*/
/*fValue = VoxelTypeTraits<DensityFloat>::minDensity();
QCOMPARE(fValue, -FLT_MAX);
fValue = VoxelTypeTraits<DensityFloat>::maxDensity();
QCOMPARE(fValue, FLT_MAX);*/
/*iValue = VoxelTypeTraits<Material8>::minDensity();
QCOMPARE(iValue, 0);
iValue = VoxelTypeTraits<Material8>::MaxDensity;
iValue = VoxelTypeTraits<Material8>::maxDensity();
QCOMPARE(iValue, 0);*/
iValue = VoxelTypeTraits<MaterialDensityPair44>::MinDensity;
/*iValue = VoxelTypeTraits<MaterialDensityPair44>::minDensity();
QCOMPARE(iValue, 0);
iValue = VoxelTypeTraits<MaterialDensityPair44>::MaxDensity;
QCOMPARE(iValue, 15);
iValue = VoxelTypeTraits<MaterialDensityPair44>::maxDensity();
QCOMPARE(iValue, 15);*/
}
QTEST_MAIN(TestVoxels)

View File

@ -31,7 +31,7 @@ class TestVoxels: public QObject
Q_OBJECT
private slots:
void testTraits();
void testVoxelTypeLimits();
};
#endif