More work on lod decimation.

This commit is contained in:
David Williams
2010-02-03 22:47:08 +00:00
parent 801c7f5c7f
commit d238da5fc9
5 changed files with 98 additions and 41 deletions

View File

@ -76,7 +76,7 @@ namespace PolyVox
/*void growMaterialBoundary(void);
int countMaterialBoundary(void);*/
bool isSubset(std::bitset<4> a, std::bitset<4> b);
bool isSubset(std::bitset<7> a, std::bitset<7> b);
void decimate(float fMinDotProductForCollapse = 0.999f);

View File

@ -36,9 +36,12 @@ namespace PolyVox
enum POLYVOXCORE_API VertexFlags
{
VF_ON_MATERIAL_EDGE = 0x00,
VF_ON_GEOMETRY_EDGE_X = 0x01,
VF_ON_GEOMETRY_EDGE_Y = 0x02,
VF_ON_GEOMETRY_EDGE_Z = 0x03
VF_ON_GEOMETRY_EDGE_NEG_X = 0x01,
VF_ON_GEOMETRY_EDGE_POS_X = 0x02,
VF_ON_GEOMETRY_EDGE_NEG_Y = 0x03,
VF_ON_GEOMETRY_EDGE_POS_Y = 0x04,
VF_ON_GEOMETRY_EDGE_NEG_Z = 0x05,
VF_ON_GEOMETRY_EDGE_POS_Z = 0x06,
};
class POLYVOXCORE_API SurfaceVertex
@ -51,20 +54,26 @@ namespace PolyVox
float getMaterial(void) const;
const Vector3DFloat& getNormal(void) const;
const Vector3DFloat& getPosition(void) const;
unsigned int getNoOfGeometryEdges(void) const;
//unsigned int getNoOfGeometryEdges(void) const;
bool isOnEdge(void) const;
bool isOnGeometryEdge(void) const;
bool isOnGeometryEdgeX(void) const;
bool isOnGeometryEdgeY(void) const;
bool isOnGeometryEdgeZ(void) const;
bool isOnGeometryEdgeNegX(void) const;
bool isOnGeometryEdgePosX(void) const;
bool isOnGeometryEdgeNegY(void) const;
bool isOnGeometryEdgePosY(void) const;
bool isOnGeometryEdgeNegZ(void) const;
bool isOnGeometryEdgePosZ(void) const;
bool isOnMaterialEdge(void) const;
void setMaterial(float materialToSet);
void setNormal(const Vector3DFloat& normalToSet);
void setOnGeometryEdgeX(bool bOnRegionEdge);
void setOnGeometryEdgeY(bool bOnRegionEdge);
void setOnGeometryEdgeZ(bool bOnRegionEdge);
void setOnGeometryEdgeNegX(bool bOnRegionEdge);
void setOnGeometryEdgePosX(bool bOnRegionEdge);
void setOnGeometryEdgeNegY(bool bOnRegionEdge);
void setOnGeometryEdgePosY(bool bOnRegionEdge);
void setOnGeometryEdgeNegZ(bool bOnRegionEdge);
void setOnGeometryEdgePosZ(bool bOnRegionEdge);
void setOnMaterialEdge(bool bOnMaterialEdge);
void setPosition(const Vector3DFloat& positionToSet);
@ -72,7 +81,7 @@ namespace PolyVox
Vector3DFloat position;
Vector3DFloat normal;
float material; //FIXME: This shouldn't be float on CPU?
std::bitset<4> m_bFlags;
std::bitset<7> m_bFlags;
};

View File

@ -449,11 +449,11 @@ 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 IndexedSurfacePatch::isSubset(std::bitset<4> a, std::bitset<4> b)
bool IndexedSurfacePatch::isSubset(std::bitset<7> a, std::bitset<7> b)
{
bool result = true;
for(int ct = 0; ct < 4; ct++)
for(int ct = 1; ct < 7; ct++) //Start at '1' to skip material flag
{
if(a.test(ct))
{

View File

@ -585,19 +585,25 @@ namespace PolyVox
{
uint16_t uZVolSpace = m_regSliceCurrent.getLowerCorner().getZ();
const uint16_t uZRegSpace = uZVolSpace - m_regInputCropped.getLowerCorner().getZ();
bool isZEdge = ((uZVolSpace == m_regInputCropped.getLowerCorner().getZ()) || (uZVolSpace == m_regInputCropped.getUpperCorner().getZ()));
//bool isZEdge = ((uZVolSpace == m_regInputCropped.getLowerCorner().getZ()) || (uZVolSpace == m_regInputCropped.getUpperCorner().getZ()));
bool isNegZEdge = (uZVolSpace == m_regInputCropped.getLowerCorner().getZ());
bool isPosZEdge = (uZVolSpace == m_regInputCropped.getUpperCorner().getZ());
//Iterate over each cell in the region
for(uint16_t uYVolSpace = m_regSliceCurrent.getLowerCorner().getY(); uYVolSpace <= m_regSliceCurrent.getUpperCorner().getY(); uYVolSpace += m_uStepSize)
{
const uint16_t uYRegSpace = uYVolSpace - m_regInputCropped.getLowerCorner().getY();
bool isYEdge = ((uYVolSpace == m_regInputCropped.getLowerCorner().getY()) || (uYVolSpace == m_regInputCropped.getUpperCorner().getY()));
//bool isYEdge = ((uYVolSpace == m_regInputCropped.getLowerCorner().getY()) || (uYVolSpace == m_regInputCropped.getUpperCorner().getY()));
bool isNegYEdge = (uYVolSpace == m_regInputCropped.getLowerCorner().getY());
bool isPosYEdge = (uYVolSpace == m_regInputCropped.getUpperCorner().getY());
for(uint16_t uXVolSpace = m_regSliceCurrent.getLowerCorner().getX(); uXVolSpace <= m_regSliceCurrent.getUpperCorner().getX(); uXVolSpace += m_uStepSize)
{
//Current position
const uint16_t uXRegSpace = uXVolSpace - m_regInputCropped.getLowerCorner().getX();
bool isXEdge = ((uXVolSpace == m_regInputCropped.getLowerCorner().getX()) || (uXVolSpace == m_regInputCropped.getUpperCorner().getX()));
//bool isXEdge = ((uXVolSpace == m_regInputCropped.getLowerCorner().getX()) || (uXVolSpace == m_regInputCropped.getUpperCorner().getX()));
bool isNegXEdge = (uXVolSpace == m_regInputCropped.getLowerCorner().getX());
bool isPosXEdge = (uXVolSpace == m_regInputCropped.getUpperCorner().getX());
//Determine the index into the edge table which tells us which vertices are inside of the surface
uint8_t iCubeIndex = m_pCurrentBitmask[getIndex(uXRegSpace,uYRegSpace)];
@ -624,9 +630,12 @@ namespace PolyVox
const uint8_t uMaterial = v000 | v100; //Because one of these is 0, the or operation takes the max.
SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial);
//surfaceVertex.setOnGeometryEdge(isXEdge || isYEdge || isZEdge);
surfaceVertex.setOnGeometryEdgeX(isXEdge);
surfaceVertex.setOnGeometryEdgeY(isYEdge);
surfaceVertex.setOnGeometryEdgeZ(isZEdge);
surfaceVertex.setOnGeometryEdgeNegX(isNegXEdge);
surfaceVertex.setOnGeometryEdgePosX(isPosXEdge);
surfaceVertex.setOnGeometryEdgeNegY(isNegYEdge);
surfaceVertex.setOnGeometryEdgePosY(isPosYEdge);
surfaceVertex.setOnGeometryEdgeNegZ(isNegZEdge);
surfaceVertex.setOnGeometryEdgePosZ(isPosZEdge);
uint32_t uLastVertexIndex = m_ispCurrent->addVertex(surfaceVertex);
m_pCurrentVertexIndicesX[getIndex(uXVolSpace - m_regInputCropped.getLowerCorner().getX(),uYVolSpace - m_regInputCropped.getLowerCorner().getY())] = uLastVertexIndex;
}
@ -639,9 +648,12 @@ namespace PolyVox
const uint8_t uMaterial = v000 | v010; //Because one of these is 0, the or operation takes the max.
SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial);
//surfaceVertex.setOnGeometryEdge(isXEdge || isYEdge || isZEdge);
surfaceVertex.setOnGeometryEdgeX(isXEdge);
surfaceVertex.setOnGeometryEdgeY(isYEdge);
surfaceVertex.setOnGeometryEdgeZ(isZEdge);
surfaceVertex.setOnGeometryEdgeNegX(isNegXEdge);
surfaceVertex.setOnGeometryEdgePosX(isPosXEdge);
surfaceVertex.setOnGeometryEdgeNegY(isNegYEdge);
surfaceVertex.setOnGeometryEdgePosY(isPosYEdge);
surfaceVertex.setOnGeometryEdgeNegZ(isNegZEdge);
surfaceVertex.setOnGeometryEdgePosZ(isPosZEdge);
uint32_t uLastVertexIndex = m_ispCurrent->addVertex(surfaceVertex);
m_pCurrentVertexIndicesY[getIndex(uXVolSpace - m_regInputCropped.getLowerCorner().getX(),uYVolSpace - m_regInputCropped.getLowerCorner().getY())] = uLastVertexIndex;
}
@ -654,9 +666,12 @@ namespace PolyVox
const uint8_t uMaterial = v000 | v001; //Because one of these is 0, the or operation takes the max.
SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial);
//surfaceVertex.setOnGeometryEdge(isXEdge || isYEdge || isZEdge);
surfaceVertex.setOnGeometryEdgeX(isXEdge);
surfaceVertex.setOnGeometryEdgeY(isYEdge);
surfaceVertex.setOnGeometryEdgeZ(isZEdge);
surfaceVertex.setOnGeometryEdgeNegX(isNegXEdge);
surfaceVertex.setOnGeometryEdgePosX(isPosXEdge);
surfaceVertex.setOnGeometryEdgeNegY(isNegYEdge);
surfaceVertex.setOnGeometryEdgePosY(isPosYEdge);
surfaceVertex.setOnGeometryEdgeNegZ(isNegZEdge);
surfaceVertex.setOnGeometryEdgePosZ(isPosZEdge);
uint32_t uLastVertexIndex = m_ispCurrent->addVertex(surfaceVertex);
m_pCurrentVertexIndicesZ[getIndex(uXVolSpace - m_regInputCropped.getLowerCorner().getX(),uYVolSpace - m_regInputCropped.getLowerCorner().getY())] = uLastVertexIndex;
}

View File

@ -63,13 +63,13 @@ namespace PolyVox
}
//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 SurfaceVertex::getNoOfGeometryEdges(void) const
{
unsigned int uIsOnEdgeX = static_cast<unsigned int>(isOnGeometryEdgeX());
unsigned int uIsOnEdgeY = static_cast<unsigned int>(isOnGeometryEdgeY());
unsigned int uIsOnEdgeZ = static_cast<unsigned int>(isOnGeometryEdgeZ());
return uIsOnEdgeX + uIsOnEdgeY + uIsOnEdgeZ;
}
}*/
bool SurfaceVertex::isOnEdge(void) const
{
@ -83,22 +83,40 @@ namespace PolyVox
bool SurfaceVertex::isOnGeometryEdge(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_X] || m_bFlags[VF_ON_GEOMETRY_EDGE_Y] || m_bFlags[VF_ON_GEOMETRY_EDGE_Z];
return
m_bFlags [VF_ON_GEOMETRY_EDGE_NEG_X] || m_bFlags[VF_ON_GEOMETRY_EDGE_POS_X] ||
m_bFlags [VF_ON_GEOMETRY_EDGE_NEG_Y] || m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Y] ||
m_bFlags [VF_ON_GEOMETRY_EDGE_NEG_Z] || m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Z];
}
bool SurfaceVertex::isOnGeometryEdgeX(void) const
bool SurfaceVertex::isOnGeometryEdgeNegX(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_X];
return m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_X];
}
bool SurfaceVertex::isOnGeometryEdgeY(void) const
bool SurfaceVertex::isOnGeometryEdgePosX(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_Y];
return m_bFlags[VF_ON_GEOMETRY_EDGE_POS_X];
}
bool SurfaceVertex::isOnGeometryEdgeZ(void) const
bool SurfaceVertex::isOnGeometryEdgeNegY(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_Z];
return m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_Y];
}
bool SurfaceVertex::isOnGeometryEdgePosY(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Y];
}
bool SurfaceVertex::isOnGeometryEdgeNegZ(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_Z];
}
bool SurfaceVertex::isOnGeometryEdgePosZ(void) const
{
return m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Z];
}
void SurfaceVertex::setMaterial(float materialToSet)
@ -116,19 +134,34 @@ namespace PolyVox
m_bFlags[VF_ON_MATERIAL_EDGE] = bOnMaterialEdge;
}
void SurfaceVertex::setOnGeometryEdgeX(bool bOnRegionEdge)
void SurfaceVertex::setOnGeometryEdgeNegX(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_X] = bOnRegionEdge;
m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_X] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgeY(bool bOnRegionEdge)
void SurfaceVertex::setOnGeometryEdgePosX(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_Y] = bOnRegionEdge;
m_bFlags[VF_ON_GEOMETRY_EDGE_POS_X] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgeZ(bool bOnRegionEdge)
void SurfaceVertex::setOnGeometryEdgeNegY(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_Z] = bOnRegionEdge;
m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_Y] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgePosY(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Y] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgeNegZ(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_NEG_Z] = bOnRegionEdge;
}
void SurfaceVertex::setOnGeometryEdgePosZ(bool bOnRegionEdge)
{
m_bFlags[VF_ON_GEOMETRY_EDGE_POS_Z] = bOnRegionEdge;
}
void SurfaceVertex::setPosition(const Vector3DFloat& positionToSet)