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

This commit is contained in:
David Williams 2011-12-17 22:12:30 +00:00
commit 4dd6b296c1
11 changed files with 104 additions and 69 deletions

View File

@ -49,7 +49,7 @@ void renderRegionImmediateMode(PolyVox::SurfaceMesh<PositionMaterialNormal>& mes
uint8_t material = vertex.getMaterial() + 0.5;
uint8_t material = static_cast<uint8_t>(vertex.getMaterial() + 0.5);
OpenGLColour colour = convertMaterialIDToColour(material);

View File

@ -83,7 +83,7 @@ OpenGLSurfaceMesh BuildOpenGLSurfaceMesh(const SurfaceMesh<PositionMaterialNorma
*ptr = vertex.getNormal().getZ();
ptr++;
uint8_t material = vertex.getMaterial() + 0.5;
uint8_t material = static_cast<uint8_t>(vertex.getMaterial() + 0.5);
OpenGLColour colour = convertMaterialIDToColour(material);

View File

@ -66,6 +66,11 @@ namespace PolyVox
{
}
//Private assignment operator, so client code can't abuse this class.
ConstVolumeProxy& operator=(const ConstVolumeProxy& rhs) throw()
{
}
const LargeVolume<VoxelType>& m_pVolume;
const Region& m_regValid;
};

View File

@ -44,16 +44,16 @@ namespace PolyVox
for(int32_t x = m_regSizeInVoxels.getLowerCorner().getX(); x < m_regSizeInVoxels.getUpperCorner().getX(); x++)
{
// these are always positive anyway
uint32_t regX = x - m_regSizeInVoxels.getLowerCorner().getX();
uint32_t regY = y - m_regSizeInVoxels.getLowerCorner().getY();
uint32_t regZ = z - m_regSizeInVoxels.getLowerCorner().getZ();
float regX = static_cast<float>(x - m_regSizeInVoxels.getLowerCorner().getX());
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 plusXVoxel = m_volData->getVoxelAt(x+1,y,z).getDensity() >= VoxelType::getThreshold();
if(currentVoxel > plusXVoxel)
{
uint32_t material = m_volData->getVoxelAt(x,y,z).getMaterial();
float material = static_cast<float>(m_volData->getVoxelAt(x,y,z).getMaterial());
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
@ -65,7 +65,7 @@ namespace PolyVox
}
if(currentVoxel < plusXVoxel)
{
int material = m_volData->getVoxelAt(x+1,y,z).getMaterial();
float material = static_cast<float>(m_volData->getVoxelAt(x+1,y,z).getMaterial());
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
@ -79,7 +79,7 @@ namespace PolyVox
int plusYVoxel = m_volData->getVoxelAt(x,y+1,z).getDensity() >= VoxelType::getThreshold();
if(currentVoxel > plusYVoxel)
{
int material = m_volData->getVoxelAt(x,y,z).getMaterial();
float material = static_cast<float>(m_volData->getVoxelAt(x,y,z).getMaterial());
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
@ -91,7 +91,7 @@ namespace PolyVox
}
if(currentVoxel < plusYVoxel)
{
int material = m_volData->getVoxelAt(x,y+1,z).getMaterial();
float material = static_cast<float>(m_volData->getVoxelAt(x,y+1,z).getMaterial());
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
@ -105,7 +105,7 @@ namespace PolyVox
int plusZVoxel = m_volData->getVoxelAt(x,y,z+1).getDensity() >= VoxelType::getThreshold();
if(currentVoxel > plusZVoxel)
{
int material = m_volData->getVoxelAt(x,y,z).getMaterial();
float material = static_cast<float>(m_volData->getVoxelAt(x,y,z).getMaterial());
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
@ -117,7 +117,7 @@ namespace PolyVox
}
if(currentVoxel < plusZVoxel)
{
int material = m_volData->getVoxelAt(x,y,z+1).getMaterial();
float material = static_cast<float>(m_volData->getVoxelAt(x,y,z+1).getMaterial());
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));

View File

@ -39,14 +39,21 @@ namespace PolyVox
/// funtion is used to determine what material should be assigned to the resulting mesh.
///
/// This class meets these requirements, although it only actually stores a density value.
/// For the getMaterial() function it just returens a constant value of '1'.
/// For the getMaterial() function it just returns a constant value of '1'.
///
/// \sa Material, MaterialDensityPair
////////////////////////////////////////////////////////////////////////////////
template <typename DensityType>
template <typename Type>
class Density
{
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 Type DensityType;
typedef uint8_t MaterialType;
Density() : m_uDensity(0) {}
Density(DensityType uDensity) : m_uDensity(uDensity) {}
@ -61,10 +68,10 @@ namespace PolyVox
}
DensityType getDensity() const throw() { return m_uDensity; }
uint32_t getMaterial() const throw() { return 1; }
MaterialType getMaterial() const throw() { return 1; }
void setDensity(DensityType uDensity) { m_uDensity = uDensity; }
void setMaterial(uint32_t 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)(); }

View File

@ -118,14 +118,18 @@ namespace PolyVox
template< template<typename> class SrcVolumeType, template<typename> class DestVolumeType, typename VoxelType>
void LowPassFilter<SrcVolumeType, DestVolumeType, VoxelType>::executeSAT()
{
const int border = m_uKernelSize - 1;
const uint32_t border = (m_uKernelSize - 1) / 2;
Vector3DInt32 satLowerCorner = m_regSrc.getLowerCorner() - Vector3DInt32(border+1, border+1, border+1);
Vector3DInt32 satLowerCorner = m_regSrc.getLowerCorner() - Vector3DInt32(border, border, border);
Vector3DInt32 satUpperCorner = m_regSrc.getUpperCorner() + Vector3DInt32(border, border, border);
RawVolume<uint32_t> satVolume(Region(satLowerCorner, satUpperCorner));
//Use floats for the SAT volume to ensure it works with negative
//densities and with both integral and floating point input volumes.
RawVolume<float> satVolume(Region(satLowerCorner, satUpperCorner));
//Clear to zeros (necessary?)
//FIXME - use Volume::fill() method. Implemented in base class as below
//but with optimised implementations in subclasses?
for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++)
{
for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++)
@ -137,9 +141,9 @@ namespace PolyVox
}
}
RawVolume<uint32_t>::Sampler satVolumeIter(&satVolume);
RawVolume<float>::Sampler satVolumeIter(&satVolume);
IteratorController<RawVolume<uint32_t>::Sampler> satIterCont;
IteratorController<RawVolume<float>::Sampler> satIterCont;
satIterCont.m_regValid = Region(satLowerCorner, satUpperCorner);
satIterCont.m_Iter = &satVolumeIter;
satIterCont.reset();
@ -153,9 +157,9 @@ namespace PolyVox
do
{
uint32_t previousSum = satVolumeIter.peekVoxel1nx0py0pz();
float previousSum = satVolumeIter.peekVoxel1nx0py0pz();
uint32_t currentVal = srcVolumeIter.getVoxel().getDensity();
float currentVal = static_cast<float>(srcVolumeIter.getVoxel().getDensity());
satVolumeIter.setVoxel(previousSum + currentVal);
@ -184,8 +188,8 @@ namespace PolyVox
{
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
{
uint32_t previousSum = satVolume.getVoxelAt(x,y-1,z);
uint32_t currentSum = satVolume.getVoxelAt(x,y,z);
float previousSum = satVolume.getVoxelAt(x,y-1,z);
float currentSum = satVolume.getVoxelAt(x,y,z);
satVolume.setVoxelAt(x,y,z,previousSum + currentSum);
}
@ -198,8 +202,8 @@ namespace PolyVox
{
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
{
uint32_t previousSum = satVolume.getVoxelAt(x,y,z-1);
uint32_t currentSum = satVolume.getVoxelAt(x,y,z);
float previousSum = satVolume.getVoxelAt(x,y,z-1);
float currentSum = satVolume.getVoxelAt(x,y,z);
satVolume.setVoxelAt(x,y,z,previousSum + currentSum);
}
@ -227,24 +231,24 @@ namespace PolyVox
int32_t satUpperY = iSrcY + border;
int32_t satUpperZ = iSrcZ + border;
int32_t a = satVolume.getVoxelAt(satLowerX,satLowerY,satLowerZ);
int32_t b = satVolume.getVoxelAt(satUpperX,satLowerY,satLowerZ);
int32_t c = satVolume.getVoxelAt(satLowerX,satUpperY,satLowerZ);
int32_t d = satVolume.getVoxelAt(satUpperX,satUpperY,satLowerZ);
int32_t e = satVolume.getVoxelAt(satLowerX,satLowerY,satUpperZ);
int32_t f = satVolume.getVoxelAt(satUpperX,satLowerY,satUpperZ);
int32_t g = satVolume.getVoxelAt(satLowerX,satUpperY,satUpperZ);
int32_t h = satVolume.getVoxelAt(satUpperX,satUpperY,satUpperZ);
float a = satVolume.getVoxelAt(satLowerX,satLowerY,satLowerZ);
float b = satVolume.getVoxelAt(satUpperX,satLowerY,satLowerZ);
float c = satVolume.getVoxelAt(satLowerX,satUpperY,satLowerZ);
float d = satVolume.getVoxelAt(satUpperX,satUpperY,satLowerZ);
float e = satVolume.getVoxelAt(satLowerX,satLowerY,satUpperZ);
float f = satVolume.getVoxelAt(satUpperX,satLowerY,satUpperZ);
float g = satVolume.getVoxelAt(satLowerX,satUpperY,satUpperZ);
float h = satVolume.getVoxelAt(satUpperX,satUpperY,satUpperZ);
int32_t sum = h+c-d-g-f-a+b+e;
float sum = h+c-d-g-f-a+b+e;
int32_t sideLength = border * 2 + 1;
uint32_t sideLength = border * 2 + 1;
int32_t average = sum / (sideLength*sideLength*sideLength);
float average = sum / (static_cast<float>(sideLength*sideLength*sideLength));
VoxelType voxel = m_pVolSrc->getVoxelAt(iDstX, iDstY, iDstZ);
voxel.setDensity(average);
voxel.setDensity(static_cast<typename VoxelType::DensityType>(average));
m_pVolDst->setVoxelAt(iDstX, iDstY, iDstZ, voxel);

View File

@ -43,10 +43,17 @@ namespace PolyVox
///
/// \sa Density, MaterialDensityPair
////////////////////////////////////////////////////////////////////////////////
template <typename MaterialType>
template <typename 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;
typedef Type MaterialType;
Material() : m_uMaterial(0) {}
Material(MaterialType uMaterial) : m_uMaterial(uMaterial) {}
@ -60,7 +67,7 @@ namespace PolyVox
return !(*this == rhs);
}
uint32_t getDensity() const throw()
DensityType getDensity() const throw()
{
//We don't actually have a density, so make one up based on the material.
if(m_uMaterial == 0)
@ -75,12 +82,12 @@ namespace PolyVox
MaterialType getMaterial() const throw() { return m_uMaterial; }
void setDensity(uint32_t /*uDensity*/) { assert(false); } //Cannot set density on voxel of type Material
void setDensity(DensityType /*uDensity*/) { assert(false); } //Cannot set density on voxel of type Material
void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; }
static uint32_t getMaxDensity() throw() { return 2; }
static uint32_t getMinDensity() throw() { return 0; }
static uint32_t getThreshold() throw() { return 1; }
static DensityType getMaxDensity() throw() { return 2; }
static DensityType getMinDensity() throw() { return 0; }
static DensityType getThreshold() throw() { return 1; }
private:
MaterialType m_uMaterial;

View File

@ -46,6 +46,13 @@ namespace PolyVox
class MaterialDensityPair
{
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 Type DensityType;
typedef Type MaterialType;
MaterialDensityPair() : m_uMaterial(0), m_uDensity(0) {}
MaterialDensityPair(Type uMaterial, Type uDensity) : m_uMaterial(uMaterial), m_uDensity(uDensity) {}
@ -59,19 +66,19 @@ namespace PolyVox
return !(*this == rhs);
}
Type getDensity() const throw() { return m_uDensity; }
Type getMaterial() const throw() { return m_uMaterial; }
DensityType getDensity() const throw() { return m_uDensity; }
MaterialType getMaterial() const throw() { return m_uMaterial; }
void setDensity(Type uDensity) { m_uDensity = uDensity; }
void setMaterial(Type uMaterial) { m_uMaterial = uMaterial; }
void setDensity(DensityType uDensity) { m_uDensity = uDensity; }
void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; }
static Type getMaxDensity() throw() { return (0x01 << NoOfDensityBits) - 1; }
static Type getMinDensity() throw() { return 0; }
static Type getThreshold() throw() {return 0x01 << (NoOfDensityBits - 1);}
static DensityType getMaxDensity() throw() { return (0x01 << NoOfDensityBits) - 1; }
static DensityType getMinDensity() throw() { return 0; }
static DensityType getThreshold() throw() {return 0x01 << (NoOfDensityBits - 1);}
private:
Type m_uMaterial : NoOfMaterialBits;
Type m_uDensity : NoOfDensityBits;
MaterialType m_uMaterial : NoOfMaterialBits;
DensityType m_uDensity : NoOfDensityBits;
};
typedef MaterialDensityPair<uint8_t, 4, 4> MaterialDensityPair44;

View File

@ -93,11 +93,6 @@ namespace PolyVox
std::vector<VertexType> m_vecVertices;
std::vector<LodRecord> m_vecLodRecords;
//The set of materials which are in this mesh. Only those materials
//which cover a whole triangle are counted. Materials which only
//exist on a material boundary do not count.
std::set<uint8_t> m_mapUsedMaterials;
};
template <typename VertexType>

View File

@ -103,11 +103,6 @@ namespace PolyVox
m_vecTriangleIndices.push_back(index0);
m_vecTriangleIndices.push_back(index1);
m_vecTriangleIndices.push_back(index2);
if((m_vecVertices[index0].material == m_vecVertices[index1].material) && (m_vecVertices[index0].material == m_vecVertices[index2].material))
{
m_mapUsedMaterials.insert(m_vecVertices[index0].material);
}
}
template <typename VertexType>
@ -131,7 +126,6 @@ namespace PolyVox
m_vecVertices.clear();
m_vecTriangleIndices.clear();
m_vecLodRecords.clear();
m_mapUsedMaterials.clear();
}
template <typename VertexType>

View File

@ -33,7 +33,7 @@ using namespace PolyVox;
void TestLowPassFilter::testExecute()
{
const int32_t g_uVolumeSideLength = 16;
const int32_t g_uVolumeSideLength = 8;
Region reg(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1));
@ -60,11 +60,27 @@ void TestLowPassFilter::testExecute()
LowPassFilter<RawVolume, RawVolume, Density8> pass1(&volData, reg, &resultVolume, reg, 5);
pass1.executeSAT();
pass1.execute();
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(1,2,3).getDensity()) << std::endl; // 7
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(10,6,7).getDensity()) << std::endl; // 17
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(15,2,12).getDensity()) << std::endl; // 4
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 << 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
}
QTEST_MAIN(TestLowPassFilter)