Vertices now carry general purpose 'data' rather than a 'material', though the data will be treated as a material in many cases. This is part of making the architecture more generic and involves some renaming.

This commit is contained in:
David Williams 2014-05-29 11:39:29 +02:00
parent 85c5686ff9
commit 2090b0087c
7 changed files with 45 additions and 41 deletions

View File

@ -91,13 +91,17 @@ int main(int argc, char *argv[])
//Extract the surface
auto meshLowLOD = extractMarchingCubesMesh(&volDataLowLOD, volDataLowLOD.getEnclosingRegion());
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
auto decodedMeshLowLOD = decode(meshLowLOD);
//Extract the surface
auto meshHighLOD = extractMarchingCubesMesh(&volData, PolyVox::Region(Vector3DInt32(30, 0, 0), Vector3DInt32(63, 63, 63)));
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
auto decodedMeshHighLOD = decode(meshHighLOD);
//Pass the surface to the OpenGL window
openGLWidget.addMesh(meshHighLOD, Vector3DInt32(30, 0, 0));
openGLWidget.addMesh(meshLowLOD, Vector3DInt32(0, 0, 0), 63.0f / 31.0f);
openGLWidget.addMesh(decodedMeshHighLOD, Vector3DInt32(30, 0, 0));
openGLWidget.addMesh(decodedMeshLowLOD, Vector3DInt32(0, 0, 0), 63.0f / 31.0f);
openGLWidget.setViewableRegion(volData.getEnclosingRegion());

View File

@ -92,8 +92,8 @@ public:
// Finally a surface extractor will probably output additional data. This is highly application dependant. For this example code
// we're just uploading it as a set of bytes which we can read individually, but real code will want to do something specialised here.
glEnableVertexAttribArray(2); //We're talking about shader attribute '2'
GLint size = (std::min)(sizeof(typename MeshType::VertexType::VoxelType), size_t(4)); // Can't upload more that 4 components (vec4 is GLSL's biggest type)
glVertexAttribIPointer(2, size, GL_UNSIGNED_BYTE, sizeof(typename MeshType::VertexType), (GLvoid*)(offsetof(typename MeshType::VertexType, material)));
GLint size = (std::min)(sizeof(typename MeshType::VertexType::DataType), size_t(4)); // Can't upload more that 4 components (vec4 is GLSL's biggest type)
glVertexAttribIPointer(2, size, GL_UNSIGNED_BYTE, sizeof(typename MeshType::VertexType), (GLvoid*)(offsetof(typename MeshType::VertexType, data)));
// We're done uploading and can now unbind.
glBindVertexArray(0);

View File

@ -222,7 +222,7 @@ namespace PolyVox
//No vertices matched and we've now hit an empty space. Fill it by creating a vertex. The 0.5f offset is because vertices set between voxels in order to build cubes around them.
CubicVertex<typename VolumeType::VoxelType> cubicVertex;
cubicVertex.position.setElements(static_cast<uint8_t>(uX), static_cast<uint8_t>(uY), static_cast<uint8_t>(uZ));
cubicVertex.material = uMaterialIn;
cubicVertex.data = uMaterialIn;
rEntry.iIndex = m_meshCurrent->addVertex(cubicVertex);
rEntry.uMaterial = uMaterialIn;
@ -275,9 +275,9 @@ namespace PolyVox
template<typename VolumeType, typename IsQuadNeeded>
bool CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::mergeQuads(Quad& q1, Quad& q2)
{
//All four vertices of a given quad have the same material,
//All four vertices of a given quad have the same data,
//so just check that the first pair of vertices match.
if(m_meshCurrent->getVertices()[q1.vertices[0]].material == m_meshCurrent->getVertices()[q2.vertices[0]].material)
if (m_meshCurrent->getVertices()[q1.vertices[0]].data == m_meshCurrent->getVertices()[q2.vertices[0]].data)
{
//Now check whether quad 2 is adjacent to quad one by comparing vertices.
//Adjacent quads must share two vertices, and the second quad could be to the

View File

@ -463,7 +463,7 @@ namespace PolyVox
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
surfaceVertex.position = v3dPositionAsUint;
surfaceVertex.normal = v3dNormal;
surfaceVertex.material = uMaterial;
surfaceVertex.data = uMaterial;
const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
m_pCurrentVertexIndicesX[iXVolSpace - m_regSizeInVoxels.getLowerX()][iYVolSpace - m_regSizeInVoxels.getLowerY()] = uLastVertexIndex;
@ -497,7 +497,7 @@ namespace PolyVox
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
surfaceVertex.position = v3dPositionAsUint;
surfaceVertex.normal = v3dNormal;
surfaceVertex.material = uMaterial;
surfaceVertex.data = uMaterial;
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
m_pCurrentVertexIndicesY[iXVolSpace - m_regSizeInVoxels.getLowerX()][iYVolSpace - m_regSizeInVoxels.getLowerY()] = uLastVertexIndex;
@ -530,7 +530,7 @@ namespace PolyVox
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
surfaceVertex.position = v3dPositionAsUint;
surfaceVertex.normal = v3dNormal;
surfaceVertex.material = uMaterial;
surfaceVertex.data = uMaterial;
const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
m_pCurrentVertexIndicesZ[iXVolSpace - m_regSizeInVoxels.getLowerX()][iYVolSpace - m_regSizeInVoxels.getLowerY()] = uLastVertexIndex;

View File

@ -102,9 +102,9 @@ namespace PolyVox
std::shared_ptr< Mesh<VertexType> > extractSubset(Mesh<VertexType>& inputMesh, std::set<uint8_t> setMaterials);
template <typename MeshType>
Mesh< Vertex< typename MeshType::VertexType::VoxelType > > decode(const MeshType& mesh)
Mesh< Vertex< typename MeshType::VertexType::DataType > > decode(const MeshType& mesh)
{
Mesh< Vertex< typename MeshType::VertexType::VoxelType > > result;
Mesh< Vertex< typename MeshType::VertexType::DataType > > result;
result.m_vecVertices.resize(mesh.m_vecVertices.size());
for(uint32_t ct = 0; ct < mesh.m_vecVertices.size(); ct++)

View File

@ -36,68 +36,68 @@ namespace PolyVox
#ifdef SWIG
struct Vertex
#else
template<typename _VoxelType>
template<typename _DataType>
struct POLYVOX_API Vertex
#endif
{
typedef _VoxelType VoxelType;
typedef _DataType DataType;
Vector3DFloat position;
Vector3DFloat normal;
VoxelType material;
DataType data;
};
#ifdef SWIG
struct CubicVertex
#else
template<typename _VoxelType>
template<typename _DataType>
struct POLYVOX_API CubicVertex
#endif
{
typedef _VoxelType VoxelType;
typedef _DataType DataType;
Vector3DUint8 position;
uint8_t normal;
VoxelType material;
DataType data;
};
#ifdef SWIG
struct MarchingCubesVertex
#else
template<typename _VoxelType>
template<typename _DataType>
struct POLYVOX_API MarchingCubesVertex
#endif
{
typedef _VoxelType VoxelType;
typedef _DataType DataType;
Vector3DUint16 position;
Vector3DFloat normal;
VoxelType material;
DataType data;
};
// Hopefully the compiler will implement the 'Return value optimization' here, but
// performance critical code will most likely decode the vertices in a shader anyway.
template<typename VoxelType>
Vertex<VoxelType> decode(const CubicVertex<VoxelType>& cubicVertex)
template<typename DataType>
Vertex<DataType> decode(const CubicVertex<DataType>& cubicVertex)
{
Vertex<VoxelType> result;
Vertex<DataType> result;
Vector3DUint8 temp = cubicVertex.position; // For some reason we can't cast Vector3DUint8 to Vector3DFloat - investigate why.
result.position = Vector3DFloat(temp.getX(), temp.getY(), temp.getZ()) - Vector3DFloat(0.5, 0.5, 0.5);
//result.normal = cubicVertex.normal;
result.material = cubicVertex.material;
result.data = cubicVertex.data;
return result;
}
// Hopefully the compiler will implement the 'Return value optimization' here, but
// performance critical code will most likely decode the vertices in a shader anyway.
template<typename VoxelType>
Vertex<VoxelType> decode(const MarchingCubesVertex<VoxelType>& cubicVertex)
template<typename DataType>
Vertex<DataType> decode(const MarchingCubesVertex<DataType>& cubicVertex)
{
Vertex<VoxelType> result;
Vertex<DataType> result;
result.position = Vector3DFloat(cubicVertex.position.getX(), cubicVertex.position.getY(), cubicVertex.position.getZ());
result.position *= (1.0 / 256.0);
result.normal = cubicVertex.normal;
result.material = cubicVertex.material;
result.data = cubicVertex.data;
return result;
}
}

View File

@ -162,7 +162,7 @@ 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 fExpectedData = 42.0f;
const static float fNoMaterial = 1.0f;
Mesh<MarchingCubesVertex<int8_t> > mesh;
@ -172,58 +172,58 @@ void TestSurfaceExtractor::testExecute()
}
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].material, static_cast<int8_t>(fNoMaterial));
QCOMPARE(mesh.getVertices()[uMaterialToCheck].data, static_cast<int8_t>(fExpectedData));
auto mesh1 = testForType<uint8_t>();
QCOMPARE(mesh1.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh1.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh1.getVertices()[uMaterialToCheck].material, static_cast<uint8_t>(fNoMaterial));
QCOMPARE(mesh1.getVertices()[uMaterialToCheck].data, static_cast<uint8_t>(fExpectedData));
auto mesh2 = testForType<int16_t>();
QCOMPARE(mesh2.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh2.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh2.getVertices()[uMaterialToCheck].material, static_cast<int16_t>(fNoMaterial));
QCOMPARE(mesh2.getVertices()[uMaterialToCheck].data, static_cast<int16_t>(fExpectedData));
auto mesh3 = testForType<uint16_t>();
QCOMPARE(mesh3.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh3.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh3.getVertices()[uMaterialToCheck].material, static_cast<uint16_t>(fNoMaterial));
QCOMPARE(mesh3.getVertices()[uMaterialToCheck].data, static_cast<uint16_t>(fExpectedData));
auto mesh4 = testForType<int32_t>();
QCOMPARE(mesh4.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh4.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh4.getVertices()[uMaterialToCheck].material, static_cast<int32_t>(fNoMaterial));
QCOMPARE(mesh4.getVertices()[uMaterialToCheck].data, static_cast<int32_t>(fExpectedData));
auto mesh5 = testForType<uint32_t>();
QCOMPARE(mesh5.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh5.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh5.getVertices()[uMaterialToCheck].material, static_cast<uint32_t>(fNoMaterial));
QCOMPARE(mesh5.getVertices()[uMaterialToCheck].data, static_cast<uint32_t>(fExpectedData));
auto mesh6 = testForType<float>();
QCOMPARE(mesh6.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh6.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh6.getVertices()[uMaterialToCheck].material, static_cast<float>(fNoMaterial));
QCOMPARE(mesh6.getVertices()[uMaterialToCheck].data, static_cast<float>(fExpectedData));
auto mesh7 = testForType<double>();
QCOMPARE(mesh7.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh7.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh7.getVertices()[uMaterialToCheck].material, static_cast<double>(fNoMaterial));
QCOMPARE(mesh7.getVertices()[uMaterialToCheck].data, static_cast<double>(fExpectedData));
auto mesh8 = testForType<Density8>();
QCOMPARE(mesh8.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh8.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh8.getVertices()[uMaterialToCheck].material, static_cast<Density8>(fNoMaterial));
QCOMPARE(mesh8.getVertices()[uMaterialToCheck].data, static_cast<Density8>(fExpectedData));
auto mesh9 = testForType<MaterialDensityPair88>();
QCOMPARE(mesh9.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh9.getNoOfIndices(), uExpectedIndices);
//QCOMPARE(mesh9.getVertices()[uMaterialToCheck].material, fExpectedMaterial);
//QCOMPARE(mesh9.getVertices()[uMaterialToCheck].data, fExpectedMaterial);
//Test whether the CustomSurfaceExtractor works.
/*testCustomController(floatMesh);
QCOMPARE(floatMesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(floatMesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(floatMesh.getVertices()[uMaterialToCheck].material, fNoMaterial);*/
QCOMPARE(floatMesh.getVertices()[uMaterialToCheck].data, fExpectedData);*/
}
QTEST_MAIN(TestSurfaceExtractor)