Templatised SurfaceMesh class on vertex type.

Replaced 'SurfaceVertex' with PositionMaterial and PositionMaterialNormal classes.
Different surface extractors can now work with different vertex types.
This commit is contained in:
David Williams 2010-10-17 21:13:46 +00:00
parent 56ec37f5e2
commit 9e1de4ba72
28 changed files with 460 additions and 176 deletions

View File

@ -12,11 +12,11 @@ OpenGLWidget::OpenGLWidget(QWidget *parent)
{
}
void OpenGLWidget::setSurfaceMeshToRender(const PolyVox::SurfaceMesh& surfaceMesh)
void OpenGLWidget::setSurfaceMeshToRender(const PolyVox::SurfaceMesh<PositionMaterialNormal>& surfaceMesh)
{
//Convienient access to the vertices and indices
const vector<uint32_t>& vecIndices = surfaceMesh.getIndices();
const vector<SurfaceVertex>& vecVertices = surfaceMesh.getVertices();
const vector<PositionMaterialNormal>& vecVertices = surfaceMesh.getVertices();
//Build an OpenGL index buffer
glGenBuffers(1, &indexBuffer);
@ -28,7 +28,7 @@ void OpenGLWidget::setSurfaceMeshToRender(const PolyVox::SurfaceMesh& surfaceMes
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
const GLvoid* pVertices = static_cast<const GLvoid*>(&(vecVertices[0]));
glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(SurfaceVertex), pVertices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(PositionMaterialNormal), pVertices, GL_STATIC_DRAW);
m_uBeginIndex = 0;
m_uEndIndex = vecIndices.size();
@ -95,8 +95,8 @@ void OpenGLWidget::paintGL()
//Bind the vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexPointer(3, GL_FLOAT, sizeof(SurfaceVertex), 0);
glNormalPointer(GL_FLOAT, sizeof(SurfaceVertex), (GLvoid*)12);
glVertexPointer(3, GL_FLOAT, sizeof(PositionMaterialNormal), 0);
glNormalPointer(GL_FLOAT, sizeof(PositionMaterialNormal), (GLvoid*)12);
glDrawRangeElements(GL_TRIANGLES, m_uBeginIndex, m_uEndIndex-1, m_uEndIndex - m_uBeginIndex, GL_UNSIGNED_INT, 0);
}

View File

@ -41,7 +41,7 @@ public:
void mousePressEvent(QMouseEvent* event);
//Convert a SrfaceMesh to OpenGL index/vertex buffers
void setSurfaceMeshToRender(const PolyVox::SurfaceMesh& surfaceMesh);
void setSurfaceMeshToRender(const PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal>& surfaceMesh);
protected:
//Qt OpenGL functions

View File

@ -24,7 +24,7 @@ freely, subject to the following restrictions:
#include "OpenGLWidget.h"
#include "MaterialDensityPair.h"
#include "SurfaceExtractor.h"
#include "CubicSurfaceExtractorWithNormals.h"
#include "SurfaceMesh.h"
#include "Volume.h"
@ -82,8 +82,8 @@ int main(int argc, char *argv[])
createSphereInVolume(volData, 30);
//Extract the surface
SurfaceMesh mesh;
SurfaceExtractor<MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
SurfaceMesh<PositionMaterialNormal> mesh;
CubicSurfaceExtractorWithNormals<MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
surfaceExtractor.execute();
//Pass the surface to the OpenGL window

View File

@ -29,9 +29,9 @@ freely, subject to the following restrictions:
using namespace PolyVox;
using namespace std;
void renderRegionImmediateMode(PolyVox::SurfaceMesh& mesh, unsigned int uLodLevel)
void renderRegionImmediateMode(PolyVox::SurfaceMesh<PositionMaterialNormal>& mesh, unsigned int uLodLevel)
{
const vector<SurfaceVertex>& vecVertices = mesh.getVertices();
const vector<PositionMaterialNormal>& vecVertices = mesh.getVertices();
const vector<uint32_t>& vecIndices = mesh.getIndices();
int beginIndex = mesh.m_vecLodRecords[uLodLevel].beginIndex;
@ -41,7 +41,7 @@ void renderRegionImmediateMode(PolyVox::SurfaceMesh& mesh, unsigned int uLodLeve
//for(vector<PolyVox::uint32_t>::const_iterator iterIndex = vecIndices.begin(); iterIndex != vecIndices.end(); ++iterIndex)
for(int index = beginIndex; index < endIndex; ++index)
{
const SurfaceVertex& vertex = vecVertices[vecIndices[index]];
const PositionMaterialNormal& vertex = vecVertices[vecIndices[index]];
const Vector3DFloat& v3dVertexPos = vertex.getPosition();
//const Vector3DFloat v3dRegionOffset(uRegionX * g_uRegionSideLength, uRegionY * g_uRegionSideLength, uRegionZ * g_uRegionSideLength);
const Vector3DFloat v3dFinalVertexPos = v3dVertexPos + static_cast<Vector3DFloat>(mesh.m_Region.getLowerCorner());

View File

@ -28,6 +28,6 @@ freely, subject to the following restrictions:
#include "glew/glew.h"
void renderRegionImmediateMode(PolyVox::SurfaceMesh& mesh, unsigned int uLodLevel);
void renderRegionImmediateMode(PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal>& mesh, unsigned int uLodLevel);
#endif //__OpenGLExample_OpenGLImmediateModeSupport_H__

View File

@ -29,7 +29,7 @@ freely, subject to the following restrictions:
using namespace PolyVox;
using namespace std;
OpenGLSurfaceMesh BuildOpenGLSurfaceMesh(const SurfaceMesh& mesh)
OpenGLSurfaceMesh BuildOpenGLSurfaceMesh(const SurfaceMesh<PositionMaterialNormal>& mesh)
{
//Represents our filled in OpenGL vertex and index buffer objects.
OpenGLSurfaceMesh result;
@ -38,7 +38,7 @@ OpenGLSurfaceMesh BuildOpenGLSurfaceMesh(const SurfaceMesh& mesh)
result.sourceMesh = &mesh;
//Convienient access to the vertices and indices
const vector<SurfaceVertex>& vecVertices = mesh.getVertices();
const vector<PositionMaterialNormal>& vecVertices = mesh.getVertices();
const vector<uint32_t>& vecIndices = mesh.getIndices();
//If we have any indices...
@ -62,9 +62,9 @@ OpenGLSurfaceMesh BuildOpenGLSurfaceMesh(const SurfaceMesh& mesh)
glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(GLfloat) * 9, 0, GL_STATIC_DRAW);
GLfloat* ptr = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
for(vector<SurfaceVertex>::const_iterator iterVertex = vecVertices.begin(); iterVertex != vecVertices.end(); ++iterVertex)
for(vector<PositionMaterialNormal>::const_iterator iterVertex = vecVertices.begin(); iterVertex != vecVertices.end(); ++iterVertex)
{
const SurfaceVertex& vertex = *iterVertex;
const PositionMaterialNormal& vertex = *iterVertex;
const Vector3DFloat& v3dVertexPos = vertex.getPosition();
//const Vector3DFloat v3dRegionOffset(uRegionX * g_uRegionSideLength, uRegionY * g_uRegionSideLength, uRegionZ * g_uRegionSideLength);
const Vector3DFloat v3dFinalVertexPos = v3dVertexPos + static_cast<Vector3DFloat>(mesh.m_Region.getLowerCorner());

View File

@ -33,10 +33,10 @@ struct OpenGLSurfaceMesh
GLulong noOfIndices;
GLuint indexBuffer;
GLuint vertexBuffer;
const PolyVox::SurfaceMesh* sourceMesh;
const PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal>* sourceMesh;
};
OpenGLSurfaceMesh BuildOpenGLSurfaceMesh(const PolyVox::SurfaceMesh& mesh);
OpenGLSurfaceMesh BuildOpenGLSurfaceMesh(const PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal>& mesh);
void renderRegionVertexBufferObject(const OpenGLSurfaceMesh& openGLSurfaceMesh, unsigned int uLodLevel);
#endif //__OpenGLExample_OpenGLVertexBufferObjectSupport_H__

View File

@ -89,7 +89,7 @@ void OpenGLWidget::setVolume(PolyVox::Volume<MaterialDensityPair44>* volData)
//Extract the surface for this region
//extractSurface(m_volData, 0, PolyVox::Region(regLowerCorner, regUpperCorner), meshCurrent);
polyvox_shared_ptr<SurfaceMesh> mesh(new SurfaceMesh);
polyvox_shared_ptr< SurfaceMesh<PositionMaterialNormal> > mesh(new SurfaceMesh<PositionMaterialNormal>);
SurfaceExtractor<MaterialDensityPair44> surfaceExtractor(volData, PolyVox::Region(regLowerCorner, regUpperCorner), mesh.get());
surfaceExtractor.execute();
@ -229,7 +229,7 @@ void OpenGLWidget::paintGL()
Vector3DUint8 v3dRegPos(uRegionX,uRegionY,uRegionZ);
if(m_mapSurfaceMeshes.find(v3dRegPos) != m_mapSurfaceMeshes.end())
{
polyvox_shared_ptr<SurfaceMesh> meshCurrent = m_mapSurfaceMeshes[v3dRegPos];
polyvox_shared_ptr< SurfaceMesh<PositionMaterialNormal> > meshCurrent = m_mapSurfaceMeshes[v3dRegPos];
unsigned int uLodLevel = 0; //meshCurrent->m_vecLodRecords.size() - 1;
if(m_bUseOpenGLVertexBufferObjects)
{

View File

@ -73,7 +73,7 @@ class OpenGLWidget : public QGLWidget
//Rather than storing one big mesh, the volume is broken into regions and a mesh is stored for each region
std::map<PolyVox::Vector3DUint8, OpenGLSurfaceMesh> m_mapOpenGLSurfaceMeshes;
std::map<PolyVox::Vector3DUint8, polyvox_shared_ptr<PolyVox::SurfaceMesh> > m_mapSurfaceMeshes;
std::map<PolyVox::Vector3DUint8, polyvox_shared_ptr<PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> > > m_mapSurfaceMeshes;
unsigned int m_uRegionSideLength;
unsigned int m_uVolumeWidthInRegions;

View File

@ -6,7 +6,6 @@ PROJECT(PolyVoxCore)
SET(CORE_SRC_FILES
source/ArraySizes.cpp
source/GradientEstimators.cpp
source/SurfaceMesh.cpp
source/Log.cpp
source/Mesh.cpp
source/MeshEdge.cpp
@ -24,6 +23,8 @@ SET(CORE_INC_FILES
include/ArraySizes.h
include/CubicSurfaceExtractor.h
include/CubicSurfaceExtractor.inl
include/CubicSurfaceExtractorWithNormals.h
include/CubicSurfaceExtractorWithNormals.inl
include/Filters.h
include/Filters.inl
include/GradientEstimators.inl
@ -39,6 +40,7 @@ SET(CORE_INC_FILES
include/SurfaceExtractor.h
include/SurfaceExtractor.inl
include/SurfaceMesh.h
include/SurfaceMesh.inl
include/SurfaceVertex.h
include/Vector.h
include/Vector.inl

View File

@ -35,7 +35,7 @@ namespace PolyVox
class CubicSurfaceExtractor
{
public:
CubicSurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh* result);
CubicSurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterial>* result);
void execute();
@ -45,7 +45,7 @@ namespace PolyVox
VolumeSampler<VoxelType> m_sampVolume;
//The surface patch we are currently filling.
SurfaceMesh* m_meshCurrent;
SurfaceMesh<PositionMaterial>* m_meshCurrent;
//Information about the region we are currently processing
Region m_regSizeInVoxels;

View File

@ -30,7 +30,7 @@ freely, subject to the following restrictions:
namespace PolyVox
{
template <typename VoxelType>
CubicSurfaceExtractor<VoxelType>::CubicSurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh* result)
CubicSurfaceExtractor<VoxelType>::CubicSurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterial>* result)
:m_volData(volData)
,m_sampVolume(volData)
,m_regSizeInVoxels(region)
@ -63,25 +63,25 @@ namespace PolyVox
{
int material = m_volData->getVoxelAt(x,y,z).getMaterial();
uint32_t v0 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
uint32_t v2 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), material));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), material));
m_meshCurrent->addTriangle(v0,v2,v1);
m_meshCurrent->addTriangle(v1,v2,v3);
m_meshCurrent->addTriangleCubic(v0,v2,v1);
m_meshCurrent->addTriangleCubic(v1,v2,v3);
}
if(currentVoxel < plusXVoxel)
{
int material = m_volData->getVoxelAt(x+1,y,z).getMaterial();
uint32_t v0 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
uint32_t v2 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), material));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), material));
m_meshCurrent->addTriangle(v0,v1,v2);
m_meshCurrent->addTriangle(v1,v3,v2);
m_meshCurrent->addTriangleCubic(v0,v1,v2);
m_meshCurrent->addTriangleCubic(v1,v3,v2);
}
int plusYVoxel = m_volData->getVoxelAt(x,y+1,z).getDensity() >= VoxelType::getThreshold();
@ -89,25 +89,25 @@ namespace PolyVox
{
int material = m_volData->getVoxelAt(x,y,z).getMaterial();
uint32_t v0 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
uint32_t v2 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), material));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), material));
m_meshCurrent->addTriangle(v0,v1,v2);
m_meshCurrent->addTriangle(v1,v3,v2);
m_meshCurrent->addTriangleCubic(v0,v1,v2);
m_meshCurrent->addTriangleCubic(v1,v3,v2);
}
if(currentVoxel < plusYVoxel)
{
int material = m_volData->getVoxelAt(x,y+1,z).getMaterial();
uint32_t v0 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
uint32_t v2 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), material));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), material));
m_meshCurrent->addTriangle(v0,v2,v1);
m_meshCurrent->addTriangle(v1,v2,v3);
m_meshCurrent->addTriangleCubic(v0,v2,v1);
m_meshCurrent->addTriangleCubic(v1,v2,v3);
}
int plusZVoxel = m_volData->getVoxelAt(x,y,z+1).getDensity() >= VoxelType::getThreshold();
@ -115,25 +115,25 @@ namespace PolyVox
{
int material = m_volData->getVoxelAt(x,y,z).getMaterial();
uint32_t v0 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
uint32_t v2 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), material));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), material));
m_meshCurrent->addTriangle(v0,v2,v1);
m_meshCurrent->addTriangle(v1,v2,v3);
m_meshCurrent->addTriangleCubic(v0,v2,v1);
m_meshCurrent->addTriangleCubic(v1,v2,v3);
}
if(currentVoxel < plusZVoxel)
{
int material = m_volData->getVoxelAt(x,y,z+1).getMaterial();
uint32_t v0 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
uint32_t v1 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
uint32_t v2 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(SurfaceVertex(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), material));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), material));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), material));
m_meshCurrent->addTriangle(v0,v1,v2);
m_meshCurrent->addTriangle(v1,v3,v2);
m_meshCurrent->addTriangleCubic(v0,v1,v2);
m_meshCurrent->addTriangleCubic(v1,v3,v2);
}
}
}

View File

@ -0,0 +1,58 @@
/*******************************************************************************
Copyright (c) 2005-2009 David Williams
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*******************************************************************************/
#ifndef __PolyVox_CubicSurfaceExtractorWithNormals_H__
#define __PolyVox_CubicSurfaceExtractorWithNormals_H__
#include "PolyVoxForwardDeclarations.h"
#include "VolumeSampler.h"
#include "PolyVoxImpl/TypeDef.h"
namespace PolyVox
{
template <typename VoxelType>
class CubicSurfaceExtractorWithNormals
{
public:
CubicSurfaceExtractorWithNormals(Volume<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result);
void execute();
private:
//The volume data and a sampler to access it.
Volume<VoxelType>* m_volData;
VolumeSampler<VoxelType> m_sampVolume;
//The surface patch we are currently filling.
SurfaceMesh<PositionMaterialNormal>* m_meshCurrent;
//Information about the region we are currently processing
Region m_regSizeInVoxels;
Region m_regSizeInCells;
};
}
#include "CubicSurfaceExtractorWithNormals.inl"
#endif

View File

@ -0,0 +1,150 @@
/*******************************************************************************
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 "Array.h"
#include "MaterialDensityPair.h"
#include "SurfaceMesh.h"
#include "PolyVoxImpl/MarchingCubesTables.h"
#include "SurfaceVertex.h"
namespace PolyVox
{
template <typename VoxelType>
CubicSurfaceExtractorWithNormals<VoxelType>::CubicSurfaceExtractorWithNormals(Volume<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result)
:m_volData(volData)
,m_sampVolume(volData)
,m_regSizeInVoxels(region)
,m_meshCurrent(result)
{
m_regSizeInVoxels.cropTo(m_volData->getEnclosingRegion());
m_regSizeInCells = m_regSizeInVoxels;
m_regSizeInCells.setUpperCorner(m_regSizeInCells.getUpperCorner() - Vector3DInt16(1,1,1));
m_meshCurrent->clear();
}
template <typename VoxelType>
void CubicSurfaceExtractorWithNormals<VoxelType>::execute()
{
for(uint16_t z = m_regSizeInVoxels.getLowerCorner().getZ(); z < m_regSizeInVoxels.getUpperCorner().getZ(); z++)
{
for(uint16_t y = m_regSizeInVoxels.getLowerCorner().getY(); y < m_regSizeInVoxels.getUpperCorner().getY(); y++)
{
for(uint16_t x = m_regSizeInVoxels.getLowerCorner().getX(); x < m_regSizeInVoxels.getUpperCorner().getX(); x++)
{
uint16_t regX = x - m_regSizeInVoxels.getLowerCorner().getX();
uint16_t regY = y - m_regSizeInVoxels.getLowerCorner().getY();
uint16_t regZ = 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)
{
int material = 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));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
m_meshCurrent->addTriangleCubic(v0,v2,v1);
m_meshCurrent->addTriangleCubic(v1,v2,v3);
}
if(currentVoxel < plusXVoxel)
{
int material = 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));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
m_meshCurrent->addTriangleCubic(v0,v1,v2);
m_meshCurrent->addTriangleCubic(v1,v3,v2);
}
int plusYVoxel = m_volData->getVoxelAt(x,y+1,z).getDensity() >= VoxelType::getThreshold();
if(currentVoxel > plusYVoxel)
{
int material = 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));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
m_meshCurrent->addTriangleCubic(v0,v1,v2);
m_meshCurrent->addTriangleCubic(v1,v3,v2);
}
if(currentVoxel < plusYVoxel)
{
int material = 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));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
m_meshCurrent->addTriangleCubic(v0,v2,v1);
m_meshCurrent->addTriangleCubic(v1,v2,v3);
}
int plusZVoxel = m_volData->getVoxelAt(x,y,z+1).getDensity() >= VoxelType::getThreshold();
if(currentVoxel > plusZVoxel)
{
int material = 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));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
m_meshCurrent->addTriangleCubic(v0,v2,v1);
m_meshCurrent->addTriangleCubic(v1,v2,v3);
}
if(currentVoxel < plusZVoxel)
{
int material = 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));
uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
m_meshCurrent->addTriangleCubic(v0,v1,v2);
m_meshCurrent->addTriangleCubic(v1,v3,v2);
}
}
}
}
m_meshCurrent->m_Region = m_regSizeInVoxels;
m_meshCurrent->m_vecLodRecords.clear();
LodRecord lodRecord;
lodRecord.beginIndex = 0;
lodRecord.endIndex = m_meshCurrent->getNoOfIndices();
m_meshCurrent->m_vecLodRecords.push_back(lodRecord);
}
}

View File

@ -55,7 +55,7 @@ namespace PolyVox
template <typename VoxelType>
Vector3DFloat computeSmoothSobelGradient(VolumeSampler<VoxelType>& volIter);
POLYVOXCORE_API void computeNormalsForVertices(Volume<uint8_t>* volumeData, SurfaceMesh& mesh, NormalGenerationMethod normalGenerationMethod);
POLYVOXCORE_API void computeNormalsForVertices(Volume<uint8_t>* volumeData, SurfaceMesh<PositionMaterialNormal>& mesh, NormalGenerationMethod normalGenerationMethod);
POLYVOXCORE_API Vector3DFloat computeNormal(Volume<uint8_t>* volumeData, const Vector3DFloat& v3dPos, NormalGenerationMethod normalGenerationMethod);
}

View File

@ -38,8 +38,8 @@ namespace PolyVox
{
public:
void buildFromMesh(SurfaceMesh* pMesh);
void fillMesh(SurfaceMesh* pMesh);
void buildFromMesh(SurfaceMesh<PositionMaterialNormal>* pMesh);
void fillMesh(SurfaceMesh<PositionMaterialNormal>* pMesh);
void matchEdgePairs(void);
void computeEdgeCosts(void);

View File

@ -37,7 +37,7 @@ namespace PolyVox
{
public:
MeshVertex();
SurfaceVertex m_vertexData;
PositionMaterialNormal m_vertexData;
//MeshEdge* m_pEdge;
//std::set<MeshFace*> m_faces;
//std::set<MeshEdge*> m_edges; //Edges which have this vertex as the src

View File

@ -77,9 +77,10 @@ namespace PolyVox
template <typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits> class MaterialDensityPair;
typedef MaterialDensityPair<uint8_t, 4, 4> MaterialDensityPair44;
class SurfaceMesh;
template <typename VertexType> class SurfaceMesh;
class Region;
class SurfaceVertex;
class PositionMaterial;
class PositionMaterialNormal;
template <typename VoxelType> class CubicSurfaceExtractor;
template <typename VoxelType> class SurfaceExtractor;

View File

@ -35,7 +35,7 @@ namespace PolyVox
class SurfaceExtractor
{
public:
SurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh* result);
SurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result);
void execute();
@ -84,7 +84,7 @@ namespace PolyVox
uint32_t m_uNoOfOccupiedCells;
//The surface patch we are currently filling.
SurfaceMesh* m_meshCurrent;
SurfaceMesh<PositionMaterialNormal>* m_meshCurrent;
//Information about the region we are currently processing
Region m_regSizeInVoxels;

View File

@ -30,7 +30,7 @@ freely, subject to the following restrictions:
namespace PolyVox
{
template <typename VoxelType>
SurfaceExtractor<VoxelType>::SurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh* result)
SurfaceExtractor<VoxelType>::SurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result)
:m_volData(volData)
,m_sampVolume(volData)
,m_regSizeInVoxels(region)
@ -457,7 +457,7 @@ namespace PolyVox
const uint8_t uMaterial = v000.getMaterial() | v100.getMaterial(); //Because one of these is 0, the or operation takes the max.
SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial);
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, uMaterial);
//surfaceVertex.setOnGeometryEdge(isXEdge || isYEdge || isZEdge);
surfaceVertex.setOnGeometryEdgeNegX(isNegXEdge);
surfaceVertex.setOnGeometryEdgePosX(isPosXEdge);
@ -487,7 +487,7 @@ namespace PolyVox
const uint8_t uMaterial = v000.getMaterial() | v010.getMaterial(); //Because one of these is 0, the or operation takes the max.
SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial);
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, uMaterial);
//surfaceVertex.setOnGeometryEdge(isXEdge || isYEdge || isZEdge);
surfaceVertex.setOnGeometryEdgeNegX(isNegXEdge);
surfaceVertex.setOnGeometryEdgePosX(isPosXEdge);
@ -517,7 +517,7 @@ namespace PolyVox
const uint8_t uMaterial = v000.getMaterial() | v001.getMaterial(); //Because one of these is 0, the or operation takes the max.
SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial);
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, uMaterial);
//surfaceVertex.setOnGeometryEdge(isXEdge || isYEdge || isZEdge);
surfaceVertex.setOnGeometryEdgeNegX(isNegXEdge);
surfaceVertex.setOnGeometryEdgePosX(isPosXEdge);

View File

@ -42,7 +42,8 @@ namespace PolyVox
int endIndex; //Let's put it just past the end STL style
};
class POLYVOXCORE_API SurfaceMesh
template <typename VertexType>
class SurfaceMesh
{
public:
SurfaceMesh();
@ -53,26 +54,21 @@ namespace PolyVox
uint32_t getNoOfNonUniformTrianges(void) const;
uint32_t getNoOfUniformTrianges(void) const;
uint32_t getNoOfVertices(void) const;
std::vector<SurfaceVertex>& getRawVertexData(void); //FIXME - this should be removed
const std::vector<SurfaceVertex>& getVertices(void) const;
std::vector<VertexType>& getRawVertexData(void); //FIXME - this should be removed
const std::vector<VertexType>& getVertices(void) const;
void addTriangle(uint32_t index0, uint32_t index1, uint32_t index2);
uint32_t addVertex(const SurfaceVertex& vertex);
void addTriangleCubic(uint32_t index0, uint32_t index1, uint32_t index2);
uint32_t addVertex(const VertexType& vertex);
void clear(void);
const bool isEmpty(void) const;
void smoothPositions(float fAmount, bool bIncludeGeometryEdgeVertices = false);
void sumNearbyNormals(bool bNormaliseResult = true);
polyvox_shared_ptr<SurfaceMesh> extractSubset(std::set<uint8_t> setMaterials);
polyvox_shared_ptr< SurfaceMesh<VertexType> > extractSubset(std::set<uint8_t> setMaterials);
void generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices = false);
//Vector3DInt32 m_v3dRegionPosition; //FIXME - remove this?
/*void growMaterialBoundary(void);
int countMaterialBoundary(void);*/
bool isSubset(std::bitset<VF_NO_OF_FLAGS> a, std::bitset<VF_NO_OF_FLAGS> b);
@ -90,7 +86,7 @@ namespace PolyVox
public:
std::vector<uint32_t> m_vecTriangleIndices;
std::vector<SurfaceVertex> m_vecVertices;
std::vector<VertexType> m_vecVertices;
std::vector<LodRecord> m_vecLodRecords;
@ -107,4 +103,6 @@ namespace PolyVox
};
}
#include "SurfaceMesh.inl"
#endif /* __SurfaceMesh_H__ */

View File

@ -21,8 +21,6 @@ freely, subject to the following restrictions:
distribution.
*******************************************************************************/
#include "SurfaceMesh.h"
#include <cstdlib>
#include <list>
#include <algorithm>
@ -31,26 +29,31 @@ using namespace std;
namespace PolyVox
{
SurfaceMesh::SurfaceMesh()
template <typename VertexType>
SurfaceMesh<VertexType>::SurfaceMesh()
{
m_iTimeStamp = -1;
}
SurfaceMesh::~SurfaceMesh()
template <typename VertexType>
SurfaceMesh<VertexType>::~SurfaceMesh()
{
}
const std::vector<uint32_t>& SurfaceMesh::getIndices(void) const
template <typename VertexType>
const std::vector<uint32_t>& SurfaceMesh<VertexType>::getIndices(void) const
{
return m_vecTriangleIndices;
}
uint32_t SurfaceMesh::getNoOfIndices(void) const
template <typename VertexType>
uint32_t SurfaceMesh<VertexType>::getNoOfIndices(void) const
{
return m_vecTriangleIndices.size();
}
uint32_t SurfaceMesh::getNoOfNonUniformTrianges(void) const
template <typename VertexType>
uint32_t SurfaceMesh<VertexType>::getNoOfNonUniformTrianges(void) const
{
uint32_t result = 0;
for(uint32_t i = 0; i < m_vecTriangleIndices.size() - 2; i += 3)
@ -67,7 +70,8 @@ namespace PolyVox
return result;
}
uint32_t SurfaceMesh::getNoOfUniformTrianges(void) const
template <typename VertexType>
uint32_t SurfaceMesh<VertexType>::getNoOfUniformTrianges(void) const
{
uint32_t result = 0;
for(uint32_t i = 0; i < m_vecTriangleIndices.size() - 2; i += 3)
@ -81,22 +85,26 @@ namespace PolyVox
return result;
}
uint32_t SurfaceMesh::getNoOfVertices(void) const
template <typename VertexType>
uint32_t SurfaceMesh<VertexType>::getNoOfVertices(void) const
{
return m_vecVertices.size();
}
std::vector<SurfaceVertex>& SurfaceMesh::getRawVertexData(void)
template <typename VertexType>
std::vector<VertexType>& SurfaceMesh<VertexType>::getRawVertexData(void)
{
return m_vecVertices;
}
const std::vector<SurfaceVertex>& SurfaceMesh::getVertices(void) const
template <typename VertexType>
const std::vector<VertexType>& SurfaceMesh<VertexType>::getVertices(void) const
{
return m_vecVertices;
}
void SurfaceMesh::addTriangle(uint32_t index0, uint32_t index1, uint32_t index2)
template <typename VertexType>
void SurfaceMesh<VertexType>::addTriangle(uint32_t index0, uint32_t index1, uint32_t index2)
{
m_vecTriangleIndices.push_back(index0);
m_vecTriangleIndices.push_back(index1);
@ -114,13 +122,23 @@ namespace PolyVox
}
}
uint32_t SurfaceMesh::addVertex(const SurfaceVertex& vertex)
template <typename VertexType>
void SurfaceMesh<VertexType>::addTriangleCubic(uint32_t index0, uint32_t index1, uint32_t index2)
{
m_vecTriangleIndices.push_back(index0);
m_vecTriangleIndices.push_back(index1);
m_vecTriangleIndices.push_back(index2);
}
template <typename VertexType>
uint32_t SurfaceMesh<VertexType>::addVertex(const VertexType& vertex)
{
m_vecVertices.push_back(vertex);
return m_vecVertices.size() - 1;
}
void SurfaceMesh::clear(void)
template <typename VertexType>
void SurfaceMesh<VertexType>::clear(void)
{
m_vecVertices.clear();
m_vecTriangleIndices.clear();
@ -128,7 +146,8 @@ namespace PolyVox
m_mapUsedMaterials.clear();
}
const bool SurfaceMesh::isEmpty(void) const
template <typename VertexType>
const bool SurfaceMesh<VertexType>::isEmpty(void) const
{
return (getNoOfVertices() == 0) || (getNoOfIndices() == 0);
}
@ -144,7 +163,8 @@ namespace PolyVox
/// SurfaceMesh should be smoothed. This can cause dicontinuities between
/// neighbouring patches.
////////////////////////////////////////////////////////////////////////////////
void SurfaceMesh::smoothPositions(float fAmount, bool bIncludeGeometryEdgeVertices)
template <typename VertexType>
void SurfaceMesh<VertexType>::smoothPositions(float fAmount, bool bIncludeGeometryEdgeVertices)
{
if(m_vecVertices.size() == 0) //FIXME - I don't think we should need this test, but I have seen crashes otherwise...
{
@ -162,13 +182,13 @@ namespace PolyVox
for(vector<uint32_t>::iterator iterIndex = m_vecTriangleIndices.begin(); iterIndex != m_vecTriangleIndices.end();)
{
//Get the vertex data for the triangle
SurfaceVertex& v0 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v0 = m_vecVertices[*iterIndex];
Vector3DFloat& v0New = newPositions[*iterIndex];
iterIndex++;
SurfaceVertex& v1 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v1 = m_vecVertices[*iterIndex];
Vector3DFloat& v1New = newPositions[*iterIndex];
iterIndex++;
SurfaceVertex& v2 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v2 = m_vecVertices[*iterIndex];
Vector3DFloat& v2New = newPositions[*iterIndex];
iterIndex++;
@ -220,7 +240,8 @@ namespace PolyVox
/// vertex. Usually, the resulting normals should be renormalised afterwards.
/// Note: This function can cause lighting discontinuities accross region boundaries.
////////////////////////////////////////////////////////////////////////////////
void SurfaceMesh::sumNearbyNormals(bool bNormaliseResult)
template <typename VertexType>
void SurfaceMesh<VertexType>::sumNearbyNormals(bool bNormaliseResult)
{
if(m_vecVertices.size() == 0) //FIXME - I don't think we should need this test, but I have seen crashes otherwise...
{
@ -234,13 +255,13 @@ namespace PolyVox
for(vector<uint32_t>::iterator iterIndex = m_vecTriangleIndices.begin(); iterIndex != m_vecTriangleIndices.end();)
{
SurfaceVertex& v0 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v0 = m_vecVertices[*iterIndex];
Vector3DFloat& v0New = summedNormals[*iterIndex];
iterIndex++;
SurfaceVertex& v1 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v1 = m_vecVertices[*iterIndex];
Vector3DFloat& v1New = summedNormals[*iterIndex];
iterIndex++;
SurfaceVertex& v2 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v2 = m_vecVertices[*iterIndex];
Vector3DFloat& v2New = summedNormals[*iterIndex];
iterIndex++;
@ -261,12 +282,13 @@ namespace PolyVox
}
}
void SurfaceMesh::generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices)
template <typename VertexType>
void SurfaceMesh<VertexType>::generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices)
{
Vector3DFloat offset = static_cast<Vector3DFloat>(m_Region.getLowerCorner());
//Initially zero the normals
for(vector<SurfaceVertex>::iterator iterVertex = m_vecVertices.begin(); iterVertex != m_vecVertices.end(); iterVertex++)
for(vector<PositionMaterialNormal>::iterator iterVertex = m_vecVertices.begin(); iterVertex != m_vecVertices.end(); iterVertex++)
{
if(m_Region.containsPoint(iterVertex->getPosition() + offset, 0.001))
{
@ -276,11 +298,11 @@ namespace PolyVox
for(vector<uint32_t>::iterator iterIndex = m_vecTriangleIndices.begin(); iterIndex != m_vecTriangleIndices.end();)
{
SurfaceVertex& v0 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v0 = m_vecVertices[*iterIndex];
iterIndex++;
SurfaceVertex& v1 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v1 = m_vecVertices[*iterIndex];
iterIndex++;
SurfaceVertex& v2 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v2 = m_vecVertices[*iterIndex];
iterIndex++;
Vector3DFloat triangleNormal = (v1.getPosition()-v0.getPosition()).cross(v2.getPosition()-v0.getPosition());
@ -301,7 +323,7 @@ namespace PolyVox
if(bNormalise)
{
for(vector<SurfaceVertex>::iterator iterVertex = m_vecVertices.begin(); iterVertex != m_vecVertices.end(); iterVertex++)
for(vector<PositionMaterialNormal>::iterator iterVertex = m_vecVertices.begin(); iterVertex != m_vecVertices.end(); iterVertex++)
{
Vector3DFloat normal = iterVertex->getNormal();
normal.normalise();
@ -312,7 +334,8 @@ namespace PolyVox
//This function looks at every vertex in the mesh and determines
//how many of it's neighbours have the same material.
void SurfaceMesh::countNoOfNeighboursUsingMaterial(void)
template <typename VertexType>
void SurfaceMesh<VertexType>::countNoOfNeighboursUsingMaterial(void)
{
//Find all the neighbouring vertices for each vertex
std::vector< std::set<int> > neighbouringVertices(m_vecVertices.size());
@ -347,9 +370,10 @@ namespace PolyVox
}
}
polyvox_shared_ptr<SurfaceMesh> SurfaceMesh::extractSubset(std::set<uint8_t> setMaterials)
template <typename VertexType>
polyvox_shared_ptr< SurfaceMesh<VertexType> > SurfaceMesh<VertexType>::extractSubset(std::set<uint8_t> setMaterials)
{
polyvox_shared_ptr<SurfaceMesh> result(new SurfaceMesh);
polyvox_shared_ptr< SurfaceMesh<VertexType> > result(new SurfaceMesh<VertexType>);
if(m_vecVertices.size() == 0) //FIXME - I don't think we should need this test, but I have seen crashes otherwise...
{
@ -369,9 +393,9 @@ namespace PolyVox
for(uint32_t triCt = 0; triCt < m_vecTriangleIndices.size(); triCt += 3)
{
SurfaceVertex& v0 = m_vecVertices[m_vecTriangleIndices[triCt]];
SurfaceVertex& v1 = m_vecVertices[m_vecTriangleIndices[triCt + 1]];
SurfaceVertex& v2 = m_vecVertices[m_vecTriangleIndices[triCt + 2]];
PositionMaterialNormal& v0 = m_vecVertices[m_vecTriangleIndices[triCt]];
PositionMaterialNormal& v1 = m_vecVertices[m_vecTriangleIndices[triCt + 1]];
PositionMaterialNormal& v2 = m_vecVertices[m_vecTriangleIndices[triCt + 2]];
if(
(setMaterials.find(v0.getMaterial()) != setMaterials.end()) ||
@ -427,18 +451,18 @@ namespace PolyVox
void SurfaceMesh::growMaterialBoundary(void)
{
std::vector<SurfaceVertex> vecNewVertices = m_vecVertices;
std::vector<PositionMaterialNormal> vecNewVertices = m_vecVertices;
for(vector<uint32_t>::iterator iterIndex = m_vecTriangleIndices.begin(); iterIndex != m_vecTriangleIndices.end();)
{
SurfaceVertex& v0 = m_vecVertices[*iterIndex];
SurfaceVertex& v0New = vecNewVertices[*iterIndex];
PositionMaterialNormal& v0 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v0New = vecNewVertices[*iterIndex];
iterIndex++;
SurfaceVertex& v1 = m_vecVertices[*iterIndex];
SurfaceVertex& v1New = vecNewVertices[*iterIndex];
PositionMaterialNormal& v1 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v1New = vecNewVertices[*iterIndex];
iterIndex++;
SurfaceVertex& v2 = m_vecVertices[*iterIndex];
SurfaceVertex& v2New = vecNewVertices[*iterIndex];
PositionMaterialNormal& v2 = m_vecVertices[*iterIndex];
PositionMaterialNormal& v2New = vecNewVertices[*iterIndex];
iterIndex++;
if(v0.m_bIsMaterialEdgeVertex || v1.m_bIsMaterialEdgeVertex || v2.m_bIsMaterialEdgeVertex)
@ -452,7 +476,8 @@ namespace PolyVox
m_vecVertices = vecNewVertices;
}*/
void SurfaceMesh::decimate(float fMinDotProductForCollapse)
template <typename VertexType>
void SurfaceMesh<VertexType>::decimate(float fMinDotProductForCollapse)
{
// We will need the information from this function to
// determine when material boundary edges can collapse.
@ -474,7 +499,8 @@ namespace PolyVox
}
// Returns true if every bit which is set in 'a' is also set in 'b'. The reverse does not need to be true.
bool SurfaceMesh::isSubset(std::bitset<VF_NO_OF_FLAGS> a, std::bitset<VF_NO_OF_FLAGS> b)
template <typename VertexType>
bool SurfaceMesh<VertexType>::isSubset(std::bitset<VF_NO_OF_FLAGS> a, std::bitset<VF_NO_OF_FLAGS> b)
{
bool result = true;
@ -493,7 +519,8 @@ namespace PolyVox
return result;
}
uint32_t SurfaceMesh::performDecimationPass(float fMinDotProductForCollapse)
template <typename VertexType>
uint32_t SurfaceMesh<VertexType>::performDecimationPass(float fMinDotProductForCollapse)
{
// I'm using a vector of lists here, rather than a vector of sets,
// because I don't believe that duplicaes should occur. But this
@ -782,7 +809,8 @@ namespace PolyVox
return noOfEdgesCollapsed;
}
int SurfaceMesh::noOfDegenerateTris(void)
template <typename VertexType>
int SurfaceMesh<VertexType>::noOfDegenerateTris(void)
{
int count = 0;
for(int triCt = 0; triCt < m_vecTriangleIndices.size();)
@ -802,7 +830,8 @@ namespace PolyVox
return count;
}
void SurfaceMesh::removeDegenerateTris(void)
template <typename VertexType>
void SurfaceMesh<VertexType>::removeDegenerateTris(void)
{
int noOfNonDegenerate = 0;
int targetCt = 0;

View File

@ -44,12 +44,28 @@ namespace PolyVox
VF_NO_OF_FLAGS
};
class POLYVOXCORE_API SurfaceVertex
class POLYVOXCORE_API PositionMaterial
{
public:
SurfaceVertex();
SurfaceVertex(Vector3DFloat positionToSet, float materialToSet);
SurfaceVertex(Vector3DFloat positionToSet, Vector3DFloat normalToSet, float materialToSet);
PositionMaterial();
PositionMaterial(Vector3DFloat positionToSet, float materialToSet);
float getMaterial(void) const;
const Vector3DFloat& getPosition(void) const;
void setMaterial(float materialToSet);
void setPosition(const Vector3DFloat& positionToSet);
public:
Vector3DFloat position;
float material;
};
class POLYVOXCORE_API PositionMaterialNormal
{
public:
PositionMaterialNormal();
PositionMaterialNormal(Vector3DFloat positionToSet, float materialToSet);
PositionMaterialNormal(Vector3DFloat positionToSet, Vector3DFloat normalToSet, float materialToSet);
float getMaterial(void) const;
const Vector3DFloat& getNormal(void) const;
@ -83,11 +99,6 @@ namespace PolyVox
float material; //FIXME: This shouldn't be float on CPU?
std::bitset<VF_NO_OF_FLAGS> m_bFlags;
};
//bool operator < (const SurfaceVertexIterator& lhs, const SurfaceVertexIterator& rhs);
}
#endif

View File

@ -66,12 +66,12 @@ namespace PolyVox
{
}
template <typename VoxelType>
////////////////////////////////////////////////////////////////////////////////
/// The border value is returned whenever an atempt is made to read a voxel which
/// is outside the extents of the volume.
/// \return The value used for voxels outside of the volume
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType Volume<VoxelType>::getBorderValue(void) const
{
return m_pBorderBlock->getVoxelAt(0,0,0);

View File

@ -30,10 +30,10 @@ using namespace std;
namespace PolyVox
{
void computeNormalsForVertices(Volume<uint8_t>* volumeData, SurfaceMesh& mesh, NormalGenerationMethod normalGenerationMethod)
void computeNormalsForVertices(Volume<uint8_t>* volumeData, SurfaceMesh<PositionMaterialNormal>& mesh, NormalGenerationMethod normalGenerationMethod)
{
std::vector<SurfaceVertex>& vecVertices = mesh.getRawVertexData();
std::vector<SurfaceVertex>::iterator iterSurfaceVertex = vecVertices.begin();
std::vector<PositionMaterialNormal>& vecVertices = mesh.getRawVertexData();
std::vector<PositionMaterialNormal>::iterator iterSurfaceVertex = vecVertices.begin();
while(iterSurfaceVertex != vecVertices.end())
{
const Vector3DFloat& v3dPos = iterSurfaceVertex->getPosition() + static_cast<Vector3DFloat>(mesh.m_Region.getLowerCorner());

View File

@ -29,7 +29,7 @@ freely, subject to the following restrictions:
namespace PolyVox
{
void Mesh::buildFromMesh(SurfaceMesh* pMesh)
void Mesh::buildFromMesh(SurfaceMesh<PositionMaterialNormal>* pMesh)
{
//First we copy the vertices across.
//We also keep track of where each vertex went
@ -186,7 +186,7 @@ namespace PolyVox
}
}
void Mesh::fillMesh(SurfaceMesh* pMesh)
void Mesh::fillMesh(SurfaceMesh<PositionMaterialNormal>* pMesh)
{
pMesh->clear();

View File

@ -72,8 +72,8 @@ namespace PolyVox
void MeshEdge::computeEdgeCost(Mesh* pParentMesh)
{
SurfaceVertex v0Data = m_pSrc->m_vertexData;
SurfaceVertex v1Data = m_pDest->m_vertexData;
PositionMaterialNormal v0Data = m_pSrc->m_vertexData;
PositionMaterialNormal v1Data = m_pDest->m_vertexData;
m_fCost = 1000000.0f;

View File

@ -27,41 +27,41 @@ freely, subject to the following restrictions:
namespace PolyVox
{
SurfaceVertex::SurfaceVertex()
PositionMaterialNormal::PositionMaterialNormal()
{
}
SurfaceVertex::SurfaceVertex(Vector3DFloat positionToSet, float materialToSet)
PositionMaterialNormal::PositionMaterialNormal(Vector3DFloat positionToSet, float materialToSet)
:position(positionToSet)
,material(materialToSet)
{
}
SurfaceVertex::SurfaceVertex(Vector3DFloat positionToSet, Vector3DFloat normalToSet, float materialToSet)
PositionMaterialNormal::PositionMaterialNormal(Vector3DFloat positionToSet, Vector3DFloat normalToSet, float materialToSet)
:position(positionToSet)
,normal(normalToSet)
,material(materialToSet)
{
}
float SurfaceVertex::getMaterial(void) const
float PositionMaterialNormal::getMaterial(void) const
{
return material;
}
const Vector3DFloat& SurfaceVertex::getNormal(void) const
const Vector3DFloat& PositionMaterialNormal::getNormal(void) const
{
return normal;
}
const Vector3DFloat& SurfaceVertex::getPosition(void) const
const Vector3DFloat& PositionMaterialNormal::getPosition(void) const
{
return position;
}
//Returns a value between 0-3, for how many geometry edges (X,Y,Z) this vertex is on.
/*unsigned int SurfaceVertex::getNoOfGeometryEdges(void) const
/*unsigned int PositionMaterialNormal::getNoOfGeometryEdges(void) const
{
unsigned int uIsOnEdgeX = static_cast<unsigned int>(isOnGeometryEdgeX());
unsigned int uIsOnEdgeY = static_cast<unsigned int>(isOnGeometryEdgeY());
@ -69,17 +69,17 @@ namespace PolyVox
return uIsOnEdgeX + uIsOnEdgeY + uIsOnEdgeZ;
}*/
bool SurfaceVertex::isOnEdge(void) const
bool PositionMaterialNormal::isOnEdge(void) const
{
return (isOnMaterialEdge() || isOnGeometryEdge());
}
bool SurfaceVertex::isOnMaterialEdge(void) const
bool PositionMaterialNormal::isOnMaterialEdge(void) const
{
return m_bFlags[VF_ON_MATERIAL_EDGE];
}
bool SurfaceVertex::isOnGeometryEdge(void) const
bool PositionMaterialNormal::isOnGeometryEdge(void) const
{
return
m_bFlags [VF_ON_GEOMETRY_EDGE_NEG_X] || m_bFlags[VF_ON_GEOMETRY_EDGE_POS_X] ||
@ -87,82 +87,117 @@ namespace PolyVox
m_bFlags [VF_ON_GEOMETRY_EDGE_NEG_Z] || m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Z];
}
bool SurfaceVertex::isOnGeometryEdgeNegX(void) const
bool PositionMaterialNormal::isOnGeometryEdgeNegX(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_X];
}
bool SurfaceVertex::isOnGeometryEdgePosX(void) const
bool PositionMaterialNormal::isOnGeometryEdgePosX(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_POS_X];
}
bool SurfaceVertex::isOnGeometryEdgeNegY(void) const
bool PositionMaterialNormal::isOnGeometryEdgeNegY(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_Y];
}
bool SurfaceVertex::isOnGeometryEdgePosY(void) const
bool PositionMaterialNormal::isOnGeometryEdgePosY(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Y];
}
bool SurfaceVertex::isOnGeometryEdgeNegZ(void) const
bool PositionMaterialNormal::isOnGeometryEdgeNegZ(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_Z];
}
bool SurfaceVertex::isOnGeometryEdgePosZ(void) const
bool PositionMaterialNormal::isOnGeometryEdgePosZ(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Z];
}
void SurfaceVertex::setMaterial(float materialToSet)
void PositionMaterialNormal::setMaterial(float materialToSet)
{
material = materialToSet;
}
void SurfaceVertex::setNormal(const Vector3DFloat& normalToSet)
void PositionMaterialNormal::setNormal(const Vector3DFloat& normalToSet)
{
normal = normalToSet;
}
void SurfaceVertex::setOnMaterialEdge(bool bOnMaterialEdge)
void PositionMaterialNormal::setOnMaterialEdge(bool bOnMaterialEdge)
{
m_bFlags[VF_ON_MATERIAL_EDGE] = bOnMaterialEdge;
}
void SurfaceVertex::setOnGeometryEdgeNegX(bool bOnRegionEdge)
void PositionMaterialNormal::setOnGeometryEdgeNegX(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_X] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgePosX(bool bOnRegionEdge)
void PositionMaterialNormal::setOnGeometryEdgePosX(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_POS_X] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgeNegY(bool bOnRegionEdge)
void PositionMaterialNormal::setOnGeometryEdgeNegY(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_Y] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgePosY(bool bOnRegionEdge)
void PositionMaterialNormal::setOnGeometryEdgePosY(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Y] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgeNegZ(bool bOnRegionEdge)
void PositionMaterialNormal::setOnGeometryEdgeNegZ(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_Z] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgePosZ(bool bOnRegionEdge)
void PositionMaterialNormal::setOnGeometryEdgePosZ(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Z] = bOnRegionEdge;
}
void SurfaceVertex::setPosition(const Vector3DFloat& positionToSet)
void PositionMaterialNormal::setPosition(const Vector3DFloat& positionToSet)
{
position = positionToSet;
}
////////////////////////////////////////////////////////////////////////////////
// PositionMaterial
////////////////////////////////////////////////////////////////////////////////
PositionMaterial::PositionMaterial()
{
}
PositionMaterial::PositionMaterial(Vector3DFloat positionToSet, float materialToSet)
:position(positionToSet)
,material(materialToSet)
{
}
float PositionMaterial::getMaterial(void) const
{
return material;
}
const Vector3DFloat& PositionMaterial::getPosition(void) const
{
return position;
}
void PositionMaterial::setMaterial(float materialToSet)
{
material = materialToSet;
}
void PositionMaterial::setPosition(const Vector3DFloat& positionToSet)
{
position = positionToSet;
}