More refactoring of basic voxel types. Started replacing getDensity and getMaterial with free functions.

This commit is contained in:
unknown 2012-02-18 12:12:38 +01:00
parent 4957d98518
commit 3f56ee6f72
17 changed files with 350 additions and 256 deletions

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 //And compute how far the current position is from the center of the volume
float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length(); 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 the current voxel is less than 'radius' units from the center then we make it solid.
if(fDistToCenter <= fRadius) if(fDistToCenter <= fRadius)
{ {
//Our new density value //Our new density value
uint8_t uDensity = VoxelTypeTraits<MaterialDensityPair44>::maxDensity(); uDensity = VoxelTypeTraits<MaterialDensityPair44>::maxDensity();
uMaterial = 1;
//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);
} }
//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

@ -35,7 +35,7 @@ freely, subject to the following restrictions:
//Use the PolyVox namespace //Use the PolyVox namespace
using namespace PolyVox; 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 //This vector hold the position of the center of the volume
Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2); Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2);
@ -59,13 +59,13 @@ void createSphereInVolume(SimpleVolume<Density8>& volData, float fRadius)
uint8_t uDensity = VoxelTypeTraits<Density8>::maxDensity(); uint8_t uDensity = VoxelTypeTraits<Density8>::maxDensity();
//Get the old voxel //Get the old voxel
Density8 voxel = volData.getVoxelAt(x,y,z); //uint8_t voxel = volData.getVoxelAt(x,y,z);
//Modify the density //Modify the density
voxel.setDensity(uDensity); //voxel.setDensity(uDensity);
//Wrte the voxel value into the volume //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 //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(); openGLWidget.show();
//Create an empty volume and then place a sphere in it //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); createSphereInVolume(volData, 28);
//Smooth the data - should reimplement this using LowPassFilter //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());
//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(); volumeResampler.execute();
//Extract the surface //Extract the surface
SurfaceMesh<PositionMaterialNormal> meshLowLOD; SurfaceMesh<PositionMaterialNormal> meshLowLOD;
SurfaceExtractor<RawVolume, Density8 > surfaceExtractor(&volDataLowLOD, volDataLowLOD.getEnclosingRegion(), &meshLowLOD); SurfaceExtractor<RawVolume, uint8_t > surfaceExtractor(&volDataLowLOD, volDataLowLOD.getEnclosingRegion(), &meshLowLOD);
surfaceExtractor.execute(); surfaceExtractor.execute();
meshLowLOD.scaleVertices(/*2.0f*/63.0f / 31.0f); meshLowLOD.scaleVertices(/*2.0f*/63.0f / 31.0f);
//Extract the surface //Extract the surface
SurfaceMesh<PositionMaterialNormal> meshHighLOD; 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(); surfaceExtractorHigh.execute();
meshHighLOD.translateVertices(Vector3DFloat(30, 0, 0)); meshHighLOD.translateVertices(Vector3DFloat(30, 0, 0));

View File

@ -6,8 +6,11 @@ PROJECT(PolyVoxCore)
SET(CORE_SRC_FILES SET(CORE_SRC_FILES
source/ArraySizes.cpp source/ArraySizes.cpp
source/AStarPathfinder.cpp source/AStarPathfinder.cpp
source/Density.cpp
source/GradientEstimators.cpp source/GradientEstimators.cpp
source/Log.cpp source/Log.cpp
source/Material.cpp
source/MaterialDensityPair.cpp
source/MeshDecimator.cpp source/MeshDecimator.cpp
source/Region.cpp source/Region.cpp
source/SimpleInterface.cpp source/SimpleInterface.cpp

View File

@ -91,79 +91,23 @@ namespace PolyVox
// These are the predefined density types. The 8-bit types are sufficient for many purposes (including // 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. // 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> Density8;
typedef Density<uint8_t> DensityU8;
typedef Density<int16_t> DensityI16; template<>
typedef Density<uint16_t> DensityU16; class VoxelTypeTraits< Density8 >
typedef Density<float> DensityFloat; {
typedef Density<double> DensityDouble; public:
typedef uint8_t DensityType;
static const bool HasDensity = true;
static const bool HasMaterial = false;
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static Density8::DensityType minDensity() { return std::numeric_limits<Density8::DensityType>::min(); }
static Density8::DensityType maxDensity() { return std::numeric_limits<Density8::DensityType>::max(); }
};
// 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 DensityU8 Density8;
typedef DensityU16 Density16;
// We have to define 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<> template<>
class VoxelTypeTraits< DensityI8 > typename VoxelTypeTraits<Density8>::DensityType convertToDensity(Density8 voxel);
{
public:
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static DensityI8::DensityType minDensity() { return -std::numeric_limits<DensityI8::DensityType>::max(); }
static DensityI8::DensityType maxDensity() { return std::numeric_limits<DensityI8::DensityType>::max(); }
};
template<>
class VoxelTypeTraits< DensityU8 >
{
public:
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static DensityU8::DensityType minDensity() { return std::numeric_limits<DensityU8::DensityType>::min(); }
static DensityU8::DensityType maxDensity() { return std::numeric_limits<DensityU8::DensityType>::max(); }
};
template<>
class VoxelTypeTraits< DensityI16 >
{
public:
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static DensityI16::DensityType minDensity() { return -std::numeric_limits<DensityI16::DensityType>::max(); }
static DensityI16::DensityType maxDensity() { return std::numeric_limits<DensityI16::DensityType>::max(); }
};
template<>
class VoxelTypeTraits< DensityU16 >
{
public:
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static DensityU16::DensityType minDensity() { return std::numeric_limits<DensityU16::DensityType>::min(); }
static DensityU16::DensityType maxDensity() { return std::numeric_limits<DensityU16::DensityType>::max(); }
};
template<>
class VoxelTypeTraits< DensityFloat >
{
public:
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static DensityFloat::DensityType minDensity() { return -std::numeric_limits<DensityFloat::DensityType>::max(); }
static DensityFloat::DensityType maxDensity() { return std::numeric_limits<DensityFloat::DensityType>::max(); }
};
template<>
class VoxelTypeTraits< DensityDouble >
{
public:
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static DensityDouble::DensityType minDensity() { return -std::numeric_limits<DensityDouble::DensityType>::max(); }
static DensityDouble::DensityType maxDensity() { return std::numeric_limits<DensityDouble::DensityType>::max(); }
};
} }
#endif //__PolyVox_Density_H__ #endif //__PolyVox_Density_H__

View File

@ -76,35 +76,35 @@ namespace PolyVox
VoxelType tSrcVoxel = srcSampler.getVoxel(); VoxelType tSrcVoxel = srcSampler.getVoxel();
uint32_t uDensity = 0; uint32_t uDensity = 0;
uDensity += srcSampler.peekVoxel1nx1ny1nz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1nx1ny1nz());
uDensity += srcSampler.peekVoxel1nx1ny0pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1nx1ny0pz());
uDensity += srcSampler.peekVoxel1nx1ny1pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1nx1ny1pz());
uDensity += srcSampler.peekVoxel1nx0py1nz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1nx0py1nz());
uDensity += srcSampler.peekVoxel1nx0py0pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1nx0py0pz());
uDensity += srcSampler.peekVoxel1nx0py1pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1nx0py1pz());
uDensity += srcSampler.peekVoxel1nx1py1nz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1nx1py1nz());
uDensity += srcSampler.peekVoxel1nx1py0pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1nx1py0pz());
uDensity += srcSampler.peekVoxel1nx1py1pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1nx1py1pz());
uDensity += srcSampler.peekVoxel0px1ny1nz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel0px1ny1nz());
uDensity += srcSampler.peekVoxel0px1ny0pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel0px1ny0pz());
uDensity += srcSampler.peekVoxel0px1ny1pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel0px1ny1pz());
uDensity += srcSampler.peekVoxel0px0py1nz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel0px0py1nz());
uDensity += srcSampler.peekVoxel0px0py0pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel0px0py0pz());
uDensity += srcSampler.peekVoxel0px0py1pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel0px0py1pz());
uDensity += srcSampler.peekVoxel0px1py1nz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel0px1py1nz());
uDensity += srcSampler.peekVoxel0px1py0pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel0px1py0pz());
uDensity += srcSampler.peekVoxel0px1py1pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel0px1py1pz());
uDensity += srcSampler.peekVoxel1px1ny1nz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1px1ny1nz());
uDensity += srcSampler.peekVoxel1px1ny0pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1px1ny0pz());
uDensity += srcSampler.peekVoxel1px1ny1pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1px1ny1pz());
uDensity += srcSampler.peekVoxel1px0py1nz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1px0py1nz());
uDensity += srcSampler.peekVoxel1px0py0pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1px0py0pz());
uDensity += srcSampler.peekVoxel1px0py1pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1px0py1pz());
uDensity += srcSampler.peekVoxel1px1py1nz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1px1py1nz());
uDensity += srcSampler.peekVoxel1px1py0pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1px1py0pz());
uDensity += srcSampler.peekVoxel1px1py1pz().getDensity(); uDensity += convertToDensity(srcSampler.peekVoxel1px1py1pz());
uDensity /= 27; uDensity /= 27;

View File

@ -100,20 +100,16 @@ namespace PolyVox
MaterialType m_uMaterial; MaterialType m_uMaterial;
}; };
typedef Material<uint8_t> MaterialU8; typedef Material<uint8_t> Material8;
typedef Material<uint16_t> MaterialU16; typedef Material<uint16_t> Material16;
typedef Material<uint32_t> MaterialU32;
// 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, 16, or 32 bit predefined types above instead.
typedef MaterialU8 Material8;
typedef MaterialU16 Material16;
typedef MaterialU32 Material32;
template<> template<>
class VoxelTypeTraits< MaterialU8 > class VoxelTypeTraits< Material8 >
{ {
public: public:
typedef uint8_t DensityType;
static const bool HasDensity = false;
static const bool HasMaterial = true;
static bool hasDensity() { return false; } static bool hasDensity() { return false; }
static bool hasMaterial() { return true; } static bool hasMaterial() { return true; }
static int minDensity() { assert(false); return 0; } static int minDensity() { assert(false); return 0; }
@ -121,19 +117,12 @@ namespace PolyVox
}; };
template<> template<>
class VoxelTypeTraits< MaterialU16 > class VoxelTypeTraits< Material16 >
{
public:
static bool hasDensity() { return false; }
static bool hasMaterial() { return true; }
static int minDensity() { assert(false); return 0; }
static int maxDensity() { assert(false); return 0; }
};
template<>
class VoxelTypeTraits< MaterialU32 >
{ {
public: public:
typedef uint8_t DensityType;
static const bool HasDensity = false;
static const bool HasMaterial = true;
static bool hasDensity() { return false; } static bool hasDensity() { return false; }
static bool hasMaterial() { return true; } static bool hasMaterial() { return true; }
static int minDensity() { assert(false); return 0; } static int minDensity() { assert(false); return 0; }

View File

@ -30,7 +30,7 @@ freely, subject to the following restrictions:
namespace PolyVox 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 /// 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() /// voxel type to provide both getDensity() and getMaterial() functions. The getDensity()
@ -90,6 +90,9 @@ namespace PolyVox
class VoxelTypeTraits< MaterialDensityPair44 > class VoxelTypeTraits< MaterialDensityPair44 >
{ {
public: public:
typedef uint8_t DensityType;
static const bool HasDensity = true;
static const bool HasMaterial = true;
static bool hasDensity() { return true; } static bool hasDensity() { return true; }
static bool hasMaterial() { return true; } static bool hasMaterial() { return true; }
static MaterialDensityPair44::DensityType minDensity() { return 0; } static MaterialDensityPair44::DensityType minDensity() { return 0; }
@ -100,11 +103,20 @@ namespace PolyVox
class VoxelTypeTraits< MaterialDensityPair88 > class VoxelTypeTraits< MaterialDensityPair88 >
{ {
public: public:
typedef uint8_t DensityType;
static const bool HasDensity = true;
static const bool HasMaterial = true;
static bool hasDensity() { return true; } static bool hasDensity() { return true; }
static bool hasMaterial() { return true; } static bool hasMaterial() { return true; }
static MaterialDensityPair88::DensityType minDensity() { return 0; } static MaterialDensityPair88::DensityType minDensity() { return 0; }
static MaterialDensityPair88::DensityType maxDensity() { return 255; } static MaterialDensityPair88::DensityType maxDensity() { return 255; }
}; };
template<>
typename VoxelTypeTraits<MaterialDensityPair44>::DensityType convertToDensity(MaterialDensityPair44 voxel);
template<>
typename VoxelTypeTraits<MaterialDensityPair88>::DensityType convertToDensity(MaterialDensityPair88 voxel);
} }
#endif #endif

View File

@ -32,11 +32,24 @@ freely, subject to the following restrictions:
namespace PolyVox namespace PolyVox
{ {
template<>
class VoxelTypeTraits< uint8_t >
{
public:
typedef uint8_t DensityType;
static const bool HasDensity = true;
static const bool HasMaterial = false;
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static uint8_t minDensity() { return 0; }
static uint8_t maxDensity() { return 255; }
};
template< template<typename> class VolumeType, typename VoxelType> template< template<typename> class VolumeType, typename VoxelType>
class SurfaceExtractor class SurfaceExtractor
{ {
public: public:
SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelType::DensityType tThreshold = (VoxelTypeTraits<VoxelType>::minDensity() + VoxelTypeTraits<VoxelType>::maxDensity()) / 2); SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelTypeTraits<VoxelType>::DensityType tThreshold = (VoxelTypeTraits<VoxelType>::minDensity() + VoxelTypeTraits<VoxelType>::maxDensity()) / 2);
void execute(); void execute();
@ -64,14 +77,14 @@ namespace PolyVox
//FIXME - Should actually use DensityType here, both in principle and because the maths may be //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. //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. //But watch out for when the DensityType is unsigned and the difference could be negative.
float voxel1nx = static_cast<float>(volIter.peekVoxel1nx0py0pz().getDensity()); float voxel1nx = static_cast<float>(convertToDensity(volIter.peekVoxel1nx0py0pz()));
float voxel1px = static_cast<float>(volIter.peekVoxel1px0py0pz().getDensity()); float voxel1px = static_cast<float>(convertToDensity(volIter.peekVoxel1px0py0pz()));
float voxel1ny = static_cast<float>(volIter.peekVoxel0px1ny0pz().getDensity()); float voxel1ny = static_cast<float>(convertToDensity(volIter.peekVoxel0px1ny0pz()));
float voxel1py = static_cast<float>(volIter.peekVoxel0px1py0pz().getDensity()); float voxel1py = static_cast<float>(convertToDensity(volIter.peekVoxel0px1py0pz()));
float voxel1nz = static_cast<float>(volIter.peekVoxel0px0py1nz().getDensity()); float voxel1nz = static_cast<float>(convertToDensity(volIter.peekVoxel0px0py1nz()));
float voxel1pz = static_cast<float>(volIter.peekVoxel0px0py1pz().getDensity()); float voxel1pz = static_cast<float>(convertToDensity(volIter.peekVoxel0px0py1pz()));
return Vector3DFloat return Vector3DFloat
( (
@ -89,35 +102,35 @@ namespace PolyVox
//FIXME - Should actually use DensityType here, both in principle and because the maths may be //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. //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. //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 pVoxel1nx1ny1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1ny1nz()));
const float pVoxel1nx1ny0pz = static_cast<float>(volIter.peekVoxel1nx1ny0pz().getDensity()); const float pVoxel1nx1ny0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1ny0pz()));
const float pVoxel1nx1ny1pz = static_cast<float>(volIter.peekVoxel1nx1ny1pz().getDensity()); const float pVoxel1nx1ny1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1ny1pz()));
const float pVoxel1nx0py1nz = static_cast<float>(volIter.peekVoxel1nx0py1nz().getDensity()); const float pVoxel1nx0py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx0py1nz()));
const float pVoxel1nx0py0pz = static_cast<float>(volIter.peekVoxel1nx0py0pz().getDensity()); const float pVoxel1nx0py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx0py0pz()));
const float pVoxel1nx0py1pz = static_cast<float>(volIter.peekVoxel1nx0py1pz().getDensity()); const float pVoxel1nx0py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx0py1pz()));
const float pVoxel1nx1py1nz = static_cast<float>(volIter.peekVoxel1nx1py1nz().getDensity()); const float pVoxel1nx1py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1py1nz()));
const float pVoxel1nx1py0pz = static_cast<float>(volIter.peekVoxel1nx1py0pz().getDensity()); const float pVoxel1nx1py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1py0pz()));
const float pVoxel1nx1py1pz = static_cast<float>(volIter.peekVoxel1nx1py1pz().getDensity()); const float pVoxel1nx1py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1py1pz()));
const float pVoxel0px1ny1nz = static_cast<float>(volIter.peekVoxel0px1ny1nz().getDensity()); const float pVoxel0px1ny1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1ny1nz()));
const float pVoxel0px1ny0pz = static_cast<float>(volIter.peekVoxel0px1ny0pz().getDensity()); const float pVoxel0px1ny0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1ny0pz()));
const float pVoxel0px1ny1pz = static_cast<float>(volIter.peekVoxel0px1ny1pz().getDensity()); const float pVoxel0px1ny1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1ny1pz()));
const float pVoxel0px0py1nz = static_cast<float>(volIter.peekVoxel0px0py1nz().getDensity()); const float pVoxel0px0py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px0py1nz()));
//const float pVoxel0px0py0pz = static_cast<float>(volIter.peekVoxel0px0py0pz().getDensity()); //const float pVoxel0px0py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px0py0pz()));
const float pVoxel0px0py1pz = static_cast<float>(volIter.peekVoxel0px0py1pz().getDensity()); const float pVoxel0px0py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px0py1pz()));
const float pVoxel0px1py1nz = static_cast<float>(volIter.peekVoxel0px1py1nz().getDensity()); const float pVoxel0px1py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1py1nz()));
const float pVoxel0px1py0pz = static_cast<float>(volIter.peekVoxel0px1py0pz().getDensity()); const float pVoxel0px1py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1py0pz()));
const float pVoxel0px1py1pz = static_cast<float>(volIter.peekVoxel0px1py1pz().getDensity()); const float pVoxel0px1py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1py1pz()));
const float pVoxel1px1ny1nz = static_cast<float>(volIter.peekVoxel1px1ny1nz().getDensity()); const float pVoxel1px1ny1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1ny1nz()));
const float pVoxel1px1ny0pz = static_cast<float>(volIter.peekVoxel1px1ny0pz().getDensity()); const float pVoxel1px1ny0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1ny0pz()));
const float pVoxel1px1ny1pz = static_cast<float>(volIter.peekVoxel1px1ny1pz().getDensity()); const float pVoxel1px1ny1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1ny1pz()));
const float pVoxel1px0py1nz = static_cast<float>(volIter.peekVoxel1px0py1nz().getDensity()); const float pVoxel1px0py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px0py1nz()));
const float pVoxel1px0py0pz = static_cast<float>(volIter.peekVoxel1px0py0pz().getDensity()); const float pVoxel1px0py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px0py0pz()));
const float pVoxel1px0py1pz = static_cast<float>(volIter.peekVoxel1px0py1pz().getDensity()); const float pVoxel1px0py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px0py1pz()));
const float pVoxel1px1py1nz = static_cast<float>(volIter.peekVoxel1px1py1nz().getDensity()); const float pVoxel1px1py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1py1nz()));
const float pVoxel1px1py0pz = static_cast<float>(volIter.peekVoxel1px1py0pz().getDensity()); const float pVoxel1px1py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1py0pz()));
const float pVoxel1px1py1pz = static_cast<float>(volIter.peekVoxel1px1py1pz().getDensity()); const float pVoxel1px1py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1py1pz()));
const float xGrad(- weights[0][0][0] * pVoxel1nx1ny1nz - const float xGrad(- weights[0][0][0] * pVoxel1nx1ny1nz -
weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] * weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] *
@ -207,7 +220,7 @@ namespace PolyVox
Region m_regSliceCurrent; Region m_regSliceCurrent;
//Our threshold value //Our threshold value
typename VoxelType::DensityType m_tThreshold; typename VoxelTypeTraits<VoxelType>::DensityType m_tThreshold;
}; };
} }

View File

@ -24,7 +24,7 @@ freely, subject to the following restrictions:
namespace PolyVox namespace PolyVox
{ {
template< template<typename> class VolumeType, typename VoxelType> template< template<typename> class VolumeType, typename VoxelType>
SurfaceExtractor<VolumeType, VoxelType>::SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelType::DensityType tThreshold) SurfaceExtractor<VolumeType, VoxelType>::SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelTypeTraits<VoxelType>::DensityType tThreshold)
:m_volData(volData) :m_volData(volData)
,m_sampVolume(volData) ,m_sampVolume(volData)
,m_meshCurrent(result) ,m_meshCurrent(result)
@ -230,7 +230,7 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ; iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ;
if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
} }
else //previous X not available else //previous X not available
{ {
@ -248,8 +248,8 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ; iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ;
if (v011.getDensity() < m_tThreshold) iCubeIndex |= 64; if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
} }
} }
else //previous Y not available else //previous Y not available
@ -270,8 +270,8 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ; iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ;
if (v101.getDensity() < m_tThreshold) iCubeIndex |= 32; if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
} }
else //previous X not available else //previous X not available
{ {
@ -284,10 +284,10 @@ namespace PolyVox
uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace];
iCubeIndex = iPreviousCubeIndexZ >> 4; iCubeIndex = iPreviousCubeIndexZ >> 4;
if (v001.getDensity() < m_tThreshold) iCubeIndex |= 16; if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16;
if (v101.getDensity() < m_tThreshold) iCubeIndex |= 32; if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (v011.getDensity() < m_tThreshold) iCubeIndex |= 64; if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
} }
} }
} }
@ -312,8 +312,8 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY;
if (v110.getDensity() < m_tThreshold) iCubeIndex |= 8; if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
} }
else //previous X not available else //previous X not available
{ {
@ -330,10 +330,10 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexY; iCubeIndex = iPreviousCubeIndexY;
if (v010.getDensity() < m_tThreshold) iCubeIndex |= 4; if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4;
if (v110.getDensity() < m_tThreshold) iCubeIndex |= 8; if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (v011.getDensity() < m_tThreshold) iCubeIndex |= 64; if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
} }
} }
else //previous Y not available else //previous Y not available
@ -353,10 +353,10 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexX; iCubeIndex = iPreviousCubeIndexX;
if (v100.getDensity() < m_tThreshold) iCubeIndex |= 2; if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2;
if (v110.getDensity() < m_tThreshold) iCubeIndex |= 8; if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (v101.getDensity() < m_tThreshold) iCubeIndex |= 32; if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
} }
else //previous X not available else //previous X not available
{ {
@ -370,14 +370,14 @@ namespace PolyVox
v011 = m_sampVolume.peekVoxel0px1py1pz(); v011 = m_sampVolume.peekVoxel0px1py1pz();
v111 = m_sampVolume.peekVoxel1px1py1pz(); v111 = m_sampVolume.peekVoxel1px1py1pz();
if (v000.getDensity() < m_tThreshold) iCubeIndex |= 1; if (convertToDensity(v000) < m_tThreshold) iCubeIndex |= 1;
if (v100.getDensity() < m_tThreshold) iCubeIndex |= 2; if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2;
if (v010.getDensity() < m_tThreshold) iCubeIndex |= 4; if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4;
if (v110.getDensity() < m_tThreshold) iCubeIndex |= 8; if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (v001.getDensity() < m_tThreshold) iCubeIndex |= 16; if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16;
if (v101.getDensity() < m_tThreshold) iCubeIndex |= 32; if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (v011.getDensity() < m_tThreshold) iCubeIndex |= 64; if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
} }
} }
} }
@ -391,6 +391,28 @@ namespace PolyVox
} }
} }
template<typename VoxelType, bool HasMaterialInType = true>
struct getMaterialFromVoxel;
template<typename VoxelType>
struct getMaterialFromVoxel<VoxelType, true>
{
static uint32_t run(VoxelType voxel)
{
return voxel.getMaterial();
}
};
template<typename VoxelType>
struct getMaterialFromVoxel<VoxelType, false>
{
static uint32_t run(VoxelType voxel)
{
return 0;
}
};
template< template<typename> class VolumeType, typename VoxelType> template< template<typename> class VolumeType, typename VoxelType>
void SurfaceExtractor<VolumeType, VoxelType>::generateVerticesForSlice(const Array2DUint8& pCurrentBitmask, void SurfaceExtractor<VolumeType, VoxelType>::generateVerticesForSlice(const Array2DUint8& pCurrentBitmask,
Array2DInt32& m_pCurrentVertexIndicesX, Array2DInt32& m_pCurrentVertexIndicesX,
@ -433,12 +455,9 @@ namespace PolyVox
const VoxelType v100 = m_sampVolume.getVoxel(); const VoxelType v100 = m_sampVolume.getVoxel();
const Vector3DFloat n100 = computeCentralDifferenceGradient(m_sampVolume); 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>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v100) - convertToDensity(v000));
float fInterp = static_cast<float>(m_tThreshold - v000.getDensity()) / static_cast<float>(v100.getDensity() - v000.getDensity());
//fInterp = 0.5f;
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 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)); Vector3DFloat v3dNormal = (n100*fInterp) + (n000*(1-fInterp));
v3dNormal.normalise(); v3dNormal.normalise();
@ -446,11 +465,9 @@ namespace PolyVox
//Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of //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 //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. //volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component.
uint32_t uMaterial = 0; uint32_t uMaterial000 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v000);
if(VoxelTypeTraits<VoxelType>::hasMaterial()) uint32_t uMaterial100 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v100);
{ uint32_t uMaterial = (std::max)(uMaterial000, uMaterial100);
uMaterial = (std::max)(v000.getMaterial(), v100.getMaterial());
}
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial)); PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial));
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
@ -464,11 +481,9 @@ namespace PolyVox
const VoxelType v010 = m_sampVolume.getVoxel(); const VoxelType v010 = m_sampVolume.getVoxel();
const Vector3DFloat n010 = computeCentralDifferenceGradient(m_sampVolume); const Vector3DFloat n010 = computeCentralDifferenceGradient(m_sampVolume);
float fInterp = static_cast<float>(m_tThreshold - v000.getDensity()) / static_cast<float>(v010.getDensity() - v000.getDensity()); float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v010) - convertToDensity(v000));
//fInterp = 0.5f;
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 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)); Vector3DFloat v3dNormal = (n010*fInterp) + (n000*(1-fInterp));
v3dNormal.normalise(); v3dNormal.normalise();
@ -476,11 +491,9 @@ namespace PolyVox
//Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of //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 //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. //volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component.
uint32_t uMaterial = 0; uint32_t uMaterial000 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v000);
if(VoxelTypeTraits<VoxelType>::hasMaterial()) uint32_t uMaterial010 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v010);
{ uint32_t uMaterial = (std::max)(uMaterial000, uMaterial010);
uMaterial = (std::max)(v000.getMaterial(), v010.getMaterial());
}
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial)); PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial));
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
@ -494,11 +507,9 @@ namespace PolyVox
const VoxelType v001 = m_sampVolume.getVoxel(); const VoxelType v001 = m_sampVolume.getVoxel();
const Vector3DFloat n001 = computeCentralDifferenceGradient(m_sampVolume); const Vector3DFloat n001 = computeCentralDifferenceGradient(m_sampVolume);
float fInterp = static_cast<float>(m_tThreshold - v000.getDensity()) / static_cast<float>(v001.getDensity() - v000.getDensity()); float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v001) - convertToDensity(v000));
//fInterp = 0.5f;
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 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)); Vector3DFloat v3dNormal = (n001*fInterp) + (n000*(1-fInterp));
v3dNormal.normalise(); v3dNormal.normalise();
@ -506,11 +517,9 @@ namespace PolyVox
//Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of //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 //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. //volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component.
uint32_t uMaterial = 0; uint32_t uMaterial000 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v000);
if(VoxelTypeTraits<VoxelType>::hasMaterial()) uint32_t uMaterial001 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v001);
{ uint32_t uMaterial = (std::max)(uMaterial000, uMaterial001);
uMaterial = (std::max)(v000.getMaterial(), v001.getMaterial());
}
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial)); PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial));
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);

View File

@ -112,14 +112,14 @@ namespace PolyVox
VoxelType voxel110 = sampler.peekVoxel1px1py0pz(); VoxelType voxel110 = sampler.peekVoxel1px1py0pz();
VoxelType voxel111 = sampler.peekVoxel1px1py1pz(); VoxelType voxel111 = sampler.peekVoxel1px1py1pz();
VoxelType::DensityType voxel000Den = voxel000.getDensity(); VoxelTypeTraits<VoxelType>::DensityType voxel000Den = convertToDensity(voxel000);
VoxelType::DensityType voxel001Den = voxel001.getDensity(); VoxelTypeTraits<VoxelType>::DensityType voxel001Den = convertToDensity(voxel001);
VoxelType::DensityType voxel010Den = voxel010.getDensity(); VoxelTypeTraits<VoxelType>::DensityType voxel010Den = convertToDensity(voxel010);
VoxelType::DensityType voxel011Den = voxel011.getDensity(); VoxelTypeTraits<VoxelType>::DensityType voxel011Den = convertToDensity(voxel011);
VoxelType::DensityType voxel100Den = voxel100.getDensity(); VoxelTypeTraits<VoxelType>::DensityType voxel100Den = convertToDensity(voxel100);
VoxelType::DensityType voxel101Den = voxel101.getDensity(); VoxelTypeTraits<VoxelType>::DensityType voxel101Den = convertToDensity(voxel101);
VoxelType::DensityType voxel110Den = voxel110.getDensity(); VoxelTypeTraits<VoxelType>::DensityType voxel110Den = convertToDensity(voxel110);
VoxelType::DensityType voxel111Den = voxel111.getDensity(); VoxelTypeTraits<VoxelType>::DensityType voxel111Den = convertToDensity(voxel111);
//FIXME - should accept all float parameters, but GCC complains? //FIXME - should accept all float parameters, but GCC complains?
double dummy; double dummy;
@ -127,10 +127,11 @@ namespace PolyVox
sy = modf(sy, &dummy); sy = modf(sy, &dummy);
sz = modf(sz, &dummy); sz = modf(sz, &dummy);
VoxelType::DensityType uInterpolatedDensity = trilinearlyInterpolate<float>(voxel000Den,voxel100Den,voxel010Den,voxel110Den,voxel001Den,voxel101Den,voxel011Den,voxel111Den,sx,sy,sz); VoxelTypeTraits<VoxelType>::DensityType uInterpolatedDensity = trilinearlyInterpolate<float>(voxel000Den,voxel100Den,voxel010Den,voxel110Den,voxel001Den,voxel101Den,voxel011Den,voxel111Den,sx,sy,sz);
VoxelType result; VoxelType result;
result.setDensity(uInterpolatedDensity); //result.setDensity(uInterpolatedDensity);
result = uInterpolatedDensity;
m_pVolDst->setVoxelAt(dx,dy,dz,result); m_pVolDst->setVoxelAt(dx,dy,dz,result);
} }

View File

@ -68,17 +68,26 @@ namespace PolyVox
class VoxelTypeTraits class VoxelTypeTraits
{ {
public: public:
typedef uint8_t DensityType;
static const bool HasDensity = false;
static const bool HasMaterial = false;
static bool hasDensity() { return false; } static bool hasDensity() { return false; }
static bool hasMaterial() { return false; } static bool hasMaterial() { return false; }
// These default implementations return an int32_t rather than void so that the result can be // 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 coponents). Calls // 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 // 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. // needs to ensure the assignment is compilable even if hasDensity() returns false.
static int32_t minDensity() { assert(false); return 0; } static int32_t minDensity() { assert(false); return 0; }
static int32_t maxDensity() { 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__ #endif //__PolyVox_Voxel_H__

View File

@ -0,0 +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"
namespace PolyVox
{
template<>
typename VoxelTypeTraits<Density8>::DensityType convertToDensity(Density8 voxel)
{
return voxel.getDensity();
}
}

View File

@ -0,0 +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/Material.h"
namespace PolyVox
{
//template<>
//typename VoxelTypeTraits<Material8>::DensityType convertToDensity(Material8 voxel)
//{
// return voxel.getDensity();
//}
}

View File

@ -0,0 +1,39 @@
/*******************************************************************************
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/MaterialDensityPair.h"
namespace PolyVox
{
template<>
typename VoxelTypeTraits<MaterialDensityPair44>::DensityType convertToDensity(MaterialDensityPair44 voxel)
{
return voxel.getDensity();
}
template<>
typename VoxelTypeTraits<MaterialDensityPair88>::DensityType convertToDensity(MaterialDensityPair88 voxel)
{
return voxel.getDensity();
}
}

View File

@ -23,6 +23,10 @@ freely, subject to the following restrictions:
#include "PolyVoxCore/SimpleInterface.h" #include "PolyVoxCore/SimpleInterface.h"
//DOESN'T BELONG HERE - JUST FOR TESTING!!
#include "PolyVoxCore/Density.h"
#include "PolyVoxCore/MaterialDensityPair.h"
namespace PolyVox namespace PolyVox
{ {
void extractCubicMesh(Volume& volume, const Region& region, Mesh& resultMesh) void extractCubicMesh(Volume& volume, const Region& region, Mesh& resultMesh)

View File

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

View File

@ -38,7 +38,7 @@ void TestVoxels::testVoxelTypeLimits()
// It's worth testing these as they are not all explictily defined (e.g. Density8 is just a // 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. // 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>::minDensity(), Density8::DensityType(0));
QCOMPARE(VoxelTypeTraits<Density8>::maxDensity(), Density8::DensityType(255)); QCOMPARE(VoxelTypeTraits<Density8>::maxDensity(), Density8::DensityType(255));
QCOMPARE(VoxelTypeTraits<DensityI8>::minDensity(), DensityI8::DensityType(-127)); QCOMPARE(VoxelTypeTraits<DensityI8>::minDensity(), DensityI8::DensityType(-127));
@ -60,7 +60,7 @@ void TestVoxels::testVoxelTypeLimits()
QCOMPARE(VoxelTypeTraits<DensityFloat>::maxDensity(), FLT_MAX); QCOMPARE(VoxelTypeTraits<DensityFloat>::maxDensity(), FLT_MAX);
QCOMPARE(VoxelTypeTraits<DensityDouble>::minDensity(), -DBL_MAX); QCOMPARE(VoxelTypeTraits<DensityDouble>::minDensity(), -DBL_MAX);
QCOMPARE(VoxelTypeTraits<DensityDouble>::maxDensity(), DBL_MAX); QCOMPARE(VoxelTypeTraits<DensityDouble>::maxDensity(), DBL_MAX);*/
/*fValue = VoxelTypeTraits<DensityFloat>::minDensity(); /*fValue = VoxelTypeTraits<DensityFloat>::minDensity();
QCOMPARE(fValue, -FLT_MAX); QCOMPARE(fValue, -FLT_MAX);