Refactoring CubicSurfaceExtractor to free functions rather than just wrapping a class.
This commit is contained in:
parent
43bb832c46
commit
9e600c0bcb
@ -225,31 +225,8 @@ namespace PolyVox
|
||||
public:
|
||||
CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), bool bMergeQuads = true);
|
||||
|
||||
void execute();
|
||||
|
||||
private:
|
||||
IsQuadNeeded m_funcIsQuadNeededCallback;
|
||||
|
||||
//The volume data and a sampler to access it.
|
||||
VolumeType* m_volData;
|
||||
|
||||
//Information about the region we are currently processing
|
||||
Region m_regSizeInVoxels;
|
||||
|
||||
//The surface patch we are currently filling.
|
||||
MeshType* m_meshCurrent;
|
||||
|
||||
//Used to avoid creating duplicate vertices.
|
||||
Array<3, IndexAndMaterial<VolumeType> > m_previousSliceVertices;
|
||||
Array<3, IndexAndMaterial<VolumeType> > m_currentSliceVertices;
|
||||
|
||||
//During extraction we create a number of different lists of quads. All the
|
||||
//quads in a given list are in the same plane and facing in the same direction.
|
||||
std::vector< std::list<Quad> > m_vecQuads[NoOfFaces];
|
||||
|
||||
//Controls whether quad merging should be performed. This might be undesirable
|
||||
//is the user needs per-vertex attributes, or to perform per vertex lighting.
|
||||
bool m_bMergeQuads;
|
||||
};
|
||||
|
||||
// This version of the function performs the extraction into a user-provided mesh rather than allocating a mesh automatically.
|
||||
@ -269,7 +246,7 @@ namespace PolyVox
|
||||
void extractCubicMeshCustom(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), bool bMergeQuads = true)
|
||||
{
|
||||
CubicSurfaceExtractor<VolumeType, MeshType, IsQuadNeeded> extractor(volData, region, result, isQuadNeeded, bMergeQuads);
|
||||
extractor.execute();
|
||||
//extractor.execute();
|
||||
}
|
||||
|
||||
/// The CubicSurfaceExtractor creates a mesh in which each voxel appears to be rendered as a cube
|
||||
|
@ -27,61 +27,52 @@ namespace PolyVox
|
||||
{
|
||||
template<typename VolumeType, typename MeshType, typename IsQuadNeeded>
|
||||
CubicSurfaceExtractor<VolumeType, MeshType, IsQuadNeeded>::CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded, bool bMergeQuads)
|
||||
:m_volData(volData)
|
||||
,m_regSizeInVoxels(region)
|
||||
,m_meshCurrent(result)
|
||||
,m_previousSliceVertices(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2, m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2, MaxVerticesPerPosition)
|
||||
,m_currentSliceVertices(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2, m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2, MaxVerticesPerPosition)
|
||||
,m_bMergeQuads(bMergeQuads)
|
||||
{
|
||||
m_funcIsQuadNeededCallback = isQuadNeeded;
|
||||
|
||||
// This extractor has a limit as to how large the extracted region can be, because the vertex positions are encoded with a single byte per component.
|
||||
int32_t maxReionDimension = 256;
|
||||
POLYVOX_THROW_IF(region.getWidthInVoxels() > maxReionDimension, std::invalid_argument, "Requested extraction region exceeds maximum dimensions");
|
||||
POLYVOX_THROW_IF(region.getHeightInVoxels() > maxReionDimension, std::invalid_argument, "Requested extraction region exceeds maximum dimensions");
|
||||
POLYVOX_THROW_IF(region.getDepthInVoxels() > maxReionDimension, std::invalid_argument, "Requested extraction region exceeds maximum dimensions");
|
||||
}
|
||||
|
||||
template<typename VolumeType, typename MeshType, typename IsQuadNeeded>
|
||||
void CubicSurfaceExtractor<VolumeType, MeshType, IsQuadNeeded>::execute()
|
||||
{
|
||||
Timer timer;
|
||||
m_meshCurrent->clear();
|
||||
result->clear();
|
||||
|
||||
//Used to avoid creating duplicate vertices.
|
||||
Array<3, IndexAndMaterial<VolumeType> > m_previousSliceVertices(region.getUpperX() - region.getLowerX() + 2, region.getUpperY() - region.getLowerY() + 2, MaxVerticesPerPosition);
|
||||
Array<3, IndexAndMaterial<VolumeType> > m_currentSliceVertices(region.getUpperX() - region.getLowerX() + 2, region.getUpperY() - region.getLowerY() + 2, MaxVerticesPerPosition);
|
||||
|
||||
//During extraction we create a number of different lists of quads. All the
|
||||
//quads in a given list are in the same plane and facing in the same direction.
|
||||
std::vector< std::list<Quad> > m_vecQuads[NoOfFaces];
|
||||
|
||||
//uint32_t uArrayWidth = m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2;
|
||||
//uint32_t uArrayHeight = m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2;
|
||||
|
||||
//uint32_t arraySize[3]= {uArrayWidth, uArrayHeight, MaxVerticesPerPosition};
|
||||
//m_previousSliceVertices.resize(arraySize);
|
||||
//m_currentSliceVertices.resize(arraySize);
|
||||
memset(m_previousSliceVertices.getRawData(), 0xff, m_previousSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial<VolumeType>));
|
||||
memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial<VolumeType>));
|
||||
|
||||
m_vecQuads[NegativeX].resize(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2);
|
||||
m_vecQuads[PositiveX].resize(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2);
|
||||
m_vecQuads[NegativeX].resize(region.getUpperX() - region.getLowerX() + 2);
|
||||
m_vecQuads[PositiveX].resize(region.getUpperX() - region.getLowerX() + 2);
|
||||
|
||||
m_vecQuads[NegativeY].resize(m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2);
|
||||
m_vecQuads[PositiveY].resize(m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2);
|
||||
m_vecQuads[NegativeY].resize(region.getUpperY() - region.getLowerY() + 2);
|
||||
m_vecQuads[PositiveY].resize(region.getUpperY() - region.getLowerY() + 2);
|
||||
|
||||
m_vecQuads[NegativeZ].resize(m_regSizeInVoxels.getUpperZ() - m_regSizeInVoxels.getLowerZ() + 2);
|
||||
m_vecQuads[PositiveZ].resize(m_regSizeInVoxels.getUpperZ() - m_regSizeInVoxels.getLowerZ() + 2);
|
||||
m_vecQuads[NegativeZ].resize(region.getUpperZ() - region.getLowerZ() + 2);
|
||||
m_vecQuads[PositiveZ].resize(region.getUpperZ() - region.getLowerZ() + 2);
|
||||
|
||||
typename VolumeType::Sampler volumeSampler(m_volData);
|
||||
typename VolumeType::Sampler volumeSampler(volData);
|
||||
|
||||
for(int32_t z = m_regSizeInVoxels.getLowerZ(); z <= m_regSizeInVoxels.getUpperZ(); z++)
|
||||
for (int32_t z = region.getLowerZ(); z <= region.getUpperZ(); z++)
|
||||
{
|
||||
uint32_t regZ = z - m_regSizeInVoxels.getLowerZ();
|
||||
uint32_t regZ = z - region.getLowerZ();
|
||||
|
||||
for(int32_t y = m_regSizeInVoxels.getLowerY(); y <= m_regSizeInVoxels.getUpperY(); y++)
|
||||
for (int32_t y = region.getLowerY(); y <= region.getUpperY(); y++)
|
||||
{
|
||||
uint32_t regY = y - m_regSizeInVoxels.getLowerY();
|
||||
uint32_t regY = y - region.getLowerY();
|
||||
|
||||
volumeSampler.setPosition(m_regSizeInVoxels.getLowerX(),y,z);
|
||||
volumeSampler.setPosition(region.getLowerX(), y, z);
|
||||
|
||||
for(int32_t x = m_regSizeInVoxels.getLowerX(); x <= m_regSizeInVoxels.getUpperX(); x++)
|
||||
for (int32_t x = region.getLowerX(); x <= region.getUpperX(); x++)
|
||||
{
|
||||
uint32_t regX = x - m_regSizeInVoxels.getLowerX();
|
||||
uint32_t regX = x - region.getLowerX();
|
||||
|
||||
typename VolumeType::VoxelType material; //Filled in by callback
|
||||
typename VolumeType::VoxelType currentVoxel = volumeSampler.getVoxel();
|
||||
@ -90,64 +81,64 @@ namespace PolyVox
|
||||
typename VolumeType::VoxelType negZVoxel = volumeSampler.peekVoxel0px0py1nz();
|
||||
|
||||
// X
|
||||
if(m_funcIsQuadNeededCallback(currentVoxel, negXVoxel, material))
|
||||
if (isQuadNeeded(currentVoxel, negXVoxel, material))
|
||||
{
|
||||
uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v1 = addVertex(regX , regY , regZ + 1, material, m_currentSliceVertices, m_meshCurrent);
|
||||
uint32_t v2 = addVertex(regX , regY + 1, regZ + 1, material, m_currentSliceVertices, m_meshCurrent);
|
||||
uint32_t v3 = addVertex(regX , regY + 1, regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v0 = addVertex(regX, regY, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v1 = addVertex(regX, regY, regZ + 1, material, m_currentSliceVertices, result);
|
||||
uint32_t v2 = addVertex(regX, regY + 1, regZ + 1, material, m_currentSliceVertices, result);
|
||||
uint32_t v3 = addVertex(regX, regY + 1, regZ, material, m_previousSliceVertices, result);
|
||||
|
||||
m_vecQuads[NegativeX][regX].push_back(Quad(v0, v1, v2, v3));
|
||||
}
|
||||
|
||||
if(m_funcIsQuadNeededCallback(negXVoxel, currentVoxel, material))
|
||||
if (isQuadNeeded(negXVoxel, currentVoxel, material))
|
||||
{
|
||||
uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v1 = addVertex(regX , regY , regZ + 1, material, m_currentSliceVertices, m_meshCurrent);
|
||||
uint32_t v2 = addVertex(regX , regY + 1, regZ + 1, material, m_currentSliceVertices, m_meshCurrent);
|
||||
uint32_t v3 = addVertex(regX , regY + 1, regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v0 = addVertex(regX, regY, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v1 = addVertex(regX, regY, regZ + 1, material, m_currentSliceVertices, result);
|
||||
uint32_t v2 = addVertex(regX, regY + 1, regZ + 1, material, m_currentSliceVertices, result);
|
||||
uint32_t v3 = addVertex(regX, regY + 1, regZ, material, m_previousSliceVertices, result);
|
||||
|
||||
m_vecQuads[PositiveX][regX].push_back(Quad(v0, v3, v2, v1));
|
||||
}
|
||||
|
||||
// Y
|
||||
if(m_funcIsQuadNeededCallback(currentVoxel, negYVoxel, material))
|
||||
if (isQuadNeeded(currentVoxel, negYVoxel, material))
|
||||
{
|
||||
uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v1 = addVertex(regX + 1, regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v2 = addVertex(regX + 1, regY , regZ + 1, material, m_currentSliceVertices, m_meshCurrent);
|
||||
uint32_t v3 = addVertex(regX , regY , regZ + 1, material, m_currentSliceVertices, m_meshCurrent);
|
||||
uint32_t v0 = addVertex(regX, regY, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v1 = addVertex(regX + 1, regY, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v2 = addVertex(regX + 1, regY, regZ + 1, material, m_currentSliceVertices, result);
|
||||
uint32_t v3 = addVertex(regX, regY, regZ + 1, material, m_currentSliceVertices, result);
|
||||
|
||||
m_vecQuads[NegativeY][regY].push_back(Quad(v0, v1, v2, v3));
|
||||
}
|
||||
|
||||
if(m_funcIsQuadNeededCallback(negYVoxel, currentVoxel, material))
|
||||
if (isQuadNeeded(negYVoxel, currentVoxel, material))
|
||||
{
|
||||
uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v1 = addVertex(regX + 1, regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v2 = addVertex(regX + 1, regY , regZ + 1, material, m_currentSliceVertices, m_meshCurrent);
|
||||
uint32_t v3 = addVertex(regX , regY , regZ + 1, material, m_currentSliceVertices, m_meshCurrent);
|
||||
uint32_t v0 = addVertex(regX, regY, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v1 = addVertex(regX + 1, regY, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v2 = addVertex(regX + 1, regY, regZ + 1, material, m_currentSliceVertices, result);
|
||||
uint32_t v3 = addVertex(regX, regY, regZ + 1, material, m_currentSliceVertices, result);
|
||||
|
||||
m_vecQuads[PositiveY][regY].push_back(Quad(v0, v3, v2, v1));
|
||||
}
|
||||
|
||||
// Z
|
||||
if(m_funcIsQuadNeededCallback(currentVoxel, negZVoxel, material))
|
||||
if (isQuadNeeded(currentVoxel, negZVoxel, material))
|
||||
{
|
||||
uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v1 = addVertex(regX , regY + 1, regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v2 = addVertex(regX + 1, regY + 1, regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v3 = addVertex(regX + 1, regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v0 = addVertex(regX, regY, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v1 = addVertex(regX, regY + 1, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v2 = addVertex(regX + 1, regY + 1, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v3 = addVertex(regX + 1, regY, regZ, material, m_previousSliceVertices, result);
|
||||
|
||||
m_vecQuads[NegativeZ][regZ].push_back(Quad(v0, v1, v2, v3));
|
||||
}
|
||||
|
||||
if(m_funcIsQuadNeededCallback(negZVoxel, currentVoxel, material))
|
||||
if (isQuadNeeded(negZVoxel, currentVoxel, material))
|
||||
{
|
||||
uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v1 = addVertex(regX , regY + 1, regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v2 = addVertex(regX + 1, regY + 1, regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v3 = addVertex(regX + 1, regY , regZ , material, m_previousSliceVertices, m_meshCurrent);
|
||||
uint32_t v0 = addVertex(regX, regY, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v1 = addVertex(regX, regY + 1, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v2 = addVertex(regX + 1, regY + 1, regZ, material, m_previousSliceVertices, result);
|
||||
uint32_t v3 = addVertex(regX + 1, regY, regZ, material, m_previousSliceVertices, result);
|
||||
|
||||
m_vecQuads[PositiveZ][regZ].push_back(Quad(v0, v3, v2, v1));
|
||||
}
|
||||
@ -160,33 +151,33 @@ namespace PolyVox
|
||||
memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial<VolumeType>));
|
||||
}
|
||||
|
||||
for(uint32_t uFace = 0; uFace < NoOfFaces; uFace++)
|
||||
for (uint32_t uFace = 0; uFace < NoOfFaces; uFace++)
|
||||
{
|
||||
std::vector< std::list<Quad> >& vecListQuads = m_vecQuads[uFace];
|
||||
|
||||
for(uint32_t slice = 0; slice < vecListQuads.size(); slice++)
|
||||
for (uint32_t slice = 0; slice < vecListQuads.size(); slice++)
|
||||
{
|
||||
std::list<Quad>& listQuads = vecListQuads[slice];
|
||||
|
||||
if(m_bMergeQuads)
|
||||
if (bMergeQuads)
|
||||
{
|
||||
//Repeatedly call this function until it returns
|
||||
//false to indicate nothing more can be done.
|
||||
while (performQuadMerging(listQuads, m_meshCurrent)){}
|
||||
while (performQuadMerging(listQuads, result)){}
|
||||
}
|
||||
|
||||
typename std::list<Quad>::iterator iterEnd = listQuads.end();
|
||||
for(typename std::list<Quad>::iterator quadIter = listQuads.begin(); quadIter != iterEnd; quadIter++)
|
||||
for (typename std::list<Quad>::iterator quadIter = listQuads.begin(); quadIter != iterEnd; quadIter++)
|
||||
{
|
||||
Quad& quad = *quadIter;
|
||||
m_meshCurrent->addTriangle(quad.vertices[0], quad.vertices[1],quad.vertices[2]);
|
||||
m_meshCurrent->addTriangle(quad.vertices[0], quad.vertices[2],quad.vertices[3]);
|
||||
result->addTriangle(quad.vertices[0], quad.vertices[1], quad.vertices[2]);
|
||||
result->addTriangle(quad.vertices[0], quad.vertices[2], quad.vertices[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_meshCurrent->setOffset(m_regSizeInVoxels.getLowerCorner());
|
||||
m_meshCurrent->removeUnusedVertices();
|
||||
result->setOffset(region.getLowerCorner());
|
||||
result->removeUnusedVertices();
|
||||
|
||||
POLYVOX_LOG_TRACE("Cubic surface extraction took ", timer.elapsedTimeInMilliSeconds(),
|
||||
"ms (Region size = ", m_regSizeInVoxels.getWidthInVoxels(), "x", m_regSizeInVoxels.getHeightInVoxels(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user