More work on LOD - allowing material boundaries to collapse.

This commit is contained in:
David Williams 2010-02-07 22:53:13 +00:00
parent d238da5fc9
commit 1448f95b0a
4 changed files with 110 additions and 7 deletions

View File

@ -185,6 +185,8 @@ void OpenGLWidget::initializeGL()
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_LIGHT0); glEnable(GL_LIGHT0);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
} }

View File

@ -70,6 +70,7 @@ namespace PolyVox
POLYVOX_SHARED_PTR<IndexedSurfacePatch> extractSubset(std::set<uint8_t> setMaterials); POLYVOX_SHARED_PTR<IndexedSurfacePatch> extractSubset(std::set<uint8_t> setMaterials);
void generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices = false); void generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices = false);
void generateMaterialWeightedNormals();
//Vector3DInt32 m_v3dRegionPosition; //FIXME - remove this? //Vector3DInt32 m_v3dRegionPosition; //FIXME - remove this?

View File

@ -30,6 +30,7 @@ freely, subject to the following restrictions:
#include "Vector.h" #include "Vector.h"
#include <bitset> #include <bitset>
#include <vector>
namespace PolyVox namespace PolyVox
{ {
@ -80,6 +81,9 @@ namespace PolyVox
public: public:
Vector3DFloat position; Vector3DFloat position;
Vector3DFloat normal; Vector3DFloat normal;
Vector3DFloat materialNormal;
int noOfMatchingNeighbours;
std::vector<uint8_t> neighbourMaterials;
float material; //FIXME: This shouldn't be float on CPU? float material; //FIXME: This shouldn't be float on CPU?
std::bitset<7> m_bFlags; std::bitset<7> m_bFlags;
}; };

View File

@ -313,6 +313,45 @@ namespace PolyVox
} }
} }
void IndexedSurfacePatch::generateMaterialWeightedNormals()
{
std::vector< std::set<int> > neighbouringVertices(m_vecVertices.size());
for(int triCt = 0; triCt < m_vecTriangleIndices.size() / 3; triCt++)
{
int v0 = m_vecTriangleIndices[(triCt * 3 + 0)];
int v1 = m_vecTriangleIndices[(triCt * 3 + 1)];
int v2 = m_vecTriangleIndices[(triCt * 3 + 2)];
neighbouringVertices[v0].insert(v1);
neighbouringVertices[v0].insert(v2);
neighbouringVertices[v1].insert(v0);
neighbouringVertices[v1].insert(v2);
neighbouringVertices[v2].insert(v0);
neighbouringVertices[v2].insert(v1);
}
for(int vertCt = 0; vertCt < m_vecVertices.size(); vertCt++)
{
m_vecVertices[vertCt].noOfMatchingNeighbours = 0;
m_vecVertices[vertCt].neighbourMaterials.clear();
Vector3DFloat materialNormal(0,0,0);
for(std::set<int>::iterator iter = neighbouringVertices[vertCt].begin(); iter != neighbouringVertices[vertCt].end(); iter++)
{
m_vecVertices[vertCt].neighbourMaterials.push_back(m_vecVertices[*iter].getMaterial());
materialNormal += (m_vecVertices[*iter].getPosition() - m_vecVertices[vertCt].getPosition()) * m_vecVertices[vertCt].getMaterial();
if(m_vecVertices[vertCt].getMaterial() == m_vecVertices[*iter].getMaterial())
{
m_vecVertices[vertCt].noOfMatchingNeighbours++;
}
}
materialNormal.normalise();
m_vecVertices[vertCt].materialNormal = materialNormal;
}
}
POLYVOX_SHARED_PTR<IndexedSurfacePatch> IndexedSurfacePatch::extractSubset(std::set<uint8_t> setMaterials) POLYVOX_SHARED_PTR<IndexedSurfacePatch> IndexedSurfacePatch::extractSubset(std::set<uint8_t> setMaterials)
{ {
POLYVOX_SHARED_PTR<IndexedSurfacePatch> result(new IndexedSurfacePatch); POLYVOX_SHARED_PTR<IndexedSurfacePatch> result(new IndexedSurfacePatch);
@ -420,11 +459,8 @@ namespace PolyVox
void IndexedSurfacePatch::decimate(float fMinDotProductForCollapse) void IndexedSurfacePatch::decimate(float fMinDotProductForCollapse)
{ {
/* generateMaterialWeightedNormals();
Note for after holiday - This decimation is half working, but we get some undesirable collpses still. The face flip check
should stop these but doesn't quite seem to work. Also, note that before calling this function it is better if
'generateAveragedFaceNormals(true);' has been called first, as this seems to give better normals for our purposes.
*/
uint32_t noOfEdgesCollapsed = 0; uint32_t noOfEdgesCollapsed = 0;
do do
{ {
@ -532,12 +568,72 @@ namespace PolyVox
continue; continue;
} }
//For now, don't collapse vertices on mateial edges... if(m_vecVertices[v0].getMaterial() != m_vecVertices[v1].getMaterial())
if(m_vecVertices[v0].isOnMaterialEdge() || m_vecVertices[v1].isOnMaterialEdge())
{ {
continue; continue;
} }
//For now, don't collapse vertices on material edges...
if(m_vecVertices[v0].isOnMaterialEdge() || m_vecVertices[v1].isOnMaterialEdge())
{
if(true)
{
bool pass = false;
//if(m_vecVertices[v0].materialNormal.dot(m_vecVertices[v1].materialNormal) < 0.9999)
/*if(m_vecVertices[v0].isOnMaterialEdge() && m_vecVertices[v1].isOnMaterialEdge())
{
if(m_vecVertices[v0].getMaterial() == m_vecVertices[v1].getMaterial())
{
pass = true;
}
}*/
bool allMatch = false;
if(m_vecVertices[v0].noOfMatchingNeighbours == m_vecVertices[v1].noOfMatchingNeighbours)
{
if(m_vecVertices[v0].noOfMatchingNeighbours == 4)
{
allMatch = true;
}
}
bool movementValid = false;
Vector3DFloat movement = m_vecVertices[v1].getPosition() - m_vecVertices[v0].getPosition();
movement.normalise();
if(movement.dot(Vector3DFloat(0,0,1)) > 0.999)
{
movementValid = true;
}
if(movement.dot(Vector3DFloat(0,1,0)) > 0.999)
{
movementValid = true;
}
if(movement.dot(Vector3DFloat(1,0,0)) > 0.999)
{
movementValid = true;
}
if(movementValid && allMatch)
{
pass = true;
}
if(!pass)
{
continue;
}
}
else //Material collapses not allowed
{
continue;
}
}
//...or those on geometry (region) edges. //...or those on geometry (region) edges.
/*if(m_vecVertices[v0].isOnGeometryEdge() || m_vecVertices[v1].isOnGeometryEdge()) /*if(m_vecVertices[v0].isOnGeometryEdge() || m_vecVertices[v1].isOnGeometryEdge())
{ {