Merge branch 'feature/vertex-and-example-refactor' of https://bitbucket.org/volumesoffun/polyvox into feature/vertex-and-example-refactor

This commit is contained in:
David Williams 2014-06-03 15:36:45 +02:00
commit e6dc0716cd
13 changed files with 202 additions and 541 deletions

View File

@ -92,14 +92,14 @@ OpenGLMeshData buildOpenGLMeshData(const PolyVox::Mesh< PolyVox::MarchingCubesVe
// Every surface extractor outputs valid positions for the vertices, so tell OpenGL how these are laid out
glEnableVertexAttribArray(0); // Attrib '0' is the vertex positions
glVertexAttribIPointer(0, 3, GL_UNSIGNED_SHORT, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, position))); //take the first 3 floats from every sizeof(decltype(vecVertices)::value_type)
glVertexAttribIPointer(0, 3, GL_UNSIGNED_SHORT, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, encodedPosition))); //take the first 3 floats from every sizeof(decltype(vecVertices)::value_type)
// Some surface extractors also generate normals, so tell OpenGL how these are laid out. If a surface extractor
// does not generate normals then nonsense values are written into the buffer here and sghould be ignored by the
// shader. This is mostly just to simplify this example code - in a real application you will know whether your
// chosen surface extractor generates normals and can skip uploading them if not.
glEnableVertexAttribArray(1); // Attrib '1' is the vertex normals.
glVertexAttribIPointer(1, 1, GL_UNSIGNED_SHORT, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, normal)));
glVertexAttribIPointer(1, 1, GL_UNSIGNED_SHORT, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, encodedNormal)));
// 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.

View File

@ -130,8 +130,9 @@ int main(int argc, char *argv[])
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
auto decodedMesh = decode(mesh);
//Pass the surface to the OpenGL window
openGLWidget.addMesh(decodedMesh, Vector3DInt32(x, y, z));
// Pass the surface to the OpenGL window. Note that we are also passing an offset in this multi-mesh example. This is because
// the surface extractors return a mesh with 'local space' positions to reduce storage requirements and precision problems.
openGLWidget.addMesh(decodedMesh, decodedMesh.getOffset());
meshCounter++;
}

View File

@ -71,7 +71,7 @@ public:
// The GL_ARRAY_BUFFER will contain the list of vertex positions
glGenBuffers(1, &(meshData.vertexBuffer));
glBindBuffer(GL_ARRAY_BUFFER, meshData.vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(Vertex< DataType >), vecVertices.data(), GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(PolyVox::Vertex< DataType >), vecVertices.data(), GL_STATIC_DRAW);
// and GL_ELEMENT_ARRAY_BUFFER will contain the indices
glGenBuffers(1, &(meshData.indexBuffer));
@ -80,20 +80,20 @@ public:
// Every surface extractor outputs valid positions for the vertices, so tell OpenGL how these are laid out
glEnableVertexAttribArray(0); // Attrib '0' is the vertex positions
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex< DataType >), (GLvoid*)(offsetof(Vertex< DataType >, position))); //take the first 3 floats from every sizeof(decltype(vecVertices)::value_type)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(PolyVox::Vertex< DataType >), (GLvoid*)(offsetof(PolyVox::Vertex< DataType >, position))); //take the first 3 floats from every sizeof(decltype(vecVertices)::value_type)
// Some surface extractors also generate normals, so tell OpenGL how these are laid out. If a surface extractor
// does not generate normals then nonsense values are written into the buffer here and sghould be ignored by the
// shader. This is mostly just to simplify this example code - in a real application you will know whether your
// chosen surface extractor generates normals and can skip uploading them if not.
glEnableVertexAttribArray(1); // Attrib '1' is the vertex normals.
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex< DataType >), (GLvoid*)(offsetof(Vertex< DataType >, normal)));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(PolyVox::Vertex< DataType >), (GLvoid*)(offsetof(PolyVox::Vertex< DataType >, normal)));
// 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(DataType), size_t(4)); // Can't upload more that 4 components (vec4 is GLSL's biggest type)
glVertexAttribIPointer(2, size, GL_UNSIGNED_BYTE, sizeof(Vertex< DataType >), (GLvoid*)(offsetof(Vertex< DataType >, data)));
glVertexAttribIPointer(2, size, GL_UNSIGNED_BYTE, sizeof(PolyVox::Vertex< DataType >), (GLvoid*)(offsetof(PolyVox::Vertex< DataType >, data)));
// We're done uploading and can now unbind.
glBindVertexArray(0);

View File

@ -27,7 +27,6 @@ SET(CORE_SRC_FILES
source/ArraySizes.cpp
source/AStarPathfinder.cpp
source/Region.cpp
source/VertexTypes.cpp
)
#Projects headers files
@ -66,6 +65,8 @@ SET(CORE_INC_FILES
include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl
include/PolyVoxCore/Material.h
include/PolyVoxCore/MaterialDensityPair.h
include/PolyVoxCore/Mesh.h
include/PolyVoxCore/Mesh.inl
include/PolyVoxCore/MinizBlockCompressor.h
include/PolyVoxCore/MinizBlockCompressor.inl
include/PolyVoxCore/Pager.h
@ -84,13 +85,11 @@ SET(CORE_INC_FILES
include/PolyVoxCore/SimpleVolume.inl
include/PolyVoxCore/SimpleVolumeBlock.inl
include/PolyVoxCore/SimpleVolumeSampler.inl
include/PolyVoxCore/Mesh.h
include/PolyVoxCore/Mesh.inl
include/PolyVoxCore/UncompressedBlock.h
include/PolyVoxCore/UncompressedBlock.inl
include/PolyVoxCore/Vector.h
include/PolyVoxCore/Vector.inl
include/PolyVoxCore/VertexTypes.h
include/PolyVoxCore/Vertex.h
include/PolyVoxCore/VolumeResampler.h
include/PolyVoxCore/VolumeResampler.inl
include/PolyVoxCore/VoxelFilters.h

View File

@ -32,9 +32,46 @@ freely, subject to the following restrictions:
#include "PolyVoxCore/BaseVolume.h" //For wrap modes... should move these?
#include "PolyVoxCore/DefaultIsQuadNeeded.h"
#include "PolyVoxCore/Mesh.h"
#include "PolyVoxCore/Vertex.h"
namespace PolyVox
{
#ifdef SWIG
struct CubicVertex
#else
template<typename _DataType>
struct POLYVOX_API CubicVertex
#endif
{
typedef _DataType DataType;
// Each component of the position is stored as a single unsigned byte.
// The true position is found by offseting each component by 0.5f.
Vector3DUint8 encodedPosition;
// User data
DataType data;
};
/// Decodes a position from a CubicVertex
inline Vector3DFloat decode(const Vector3DUint8& encodedPosition)
{
Vector3DFloat result(encodedPosition.getX(), encodedPosition.getY(), encodedPosition.getZ());
result -= 0.5f; // Apply the required offset
return result;
}
/// Decodes a MarchingCubesVertex by converting it into a regular Vertex which can then be directly used for rendering.
template<typename DataType>
Vertex<DataType> decode(const CubicVertex<DataType>& cubicVertex)
{
Vertex<DataType> result;
result.position = decode(cubicVertex.encodedPosition);
result.normal.setElements(0.0f, 0.0f, 0.0f); // Currently not calculated
result.data = cubicVertex.data; // Data is not encoded
return result;
}
/// The CubicSurfaceExtractor creates a mesh in which each voxel appears to be rendered as a cube
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Introduction

View File

@ -190,13 +190,13 @@ namespace PolyVox
for(typename std::list<Quad>::iterator quadIter = listQuads.begin(); quadIter != iterEnd; quadIter++)
{
Quad& quad = *quadIter;
m_meshCurrent->addTriangleCubic(quad.vertices[0], quad.vertices[1],quad.vertices[2]);
m_meshCurrent->addTriangleCubic(quad.vertices[0], quad.vertices[2],quad.vertices[3]);
m_meshCurrent->addTriangle(quad.vertices[0], quad.vertices[1],quad.vertices[2]);
m_meshCurrent->addTriangle(quad.vertices[0], quad.vertices[2],quad.vertices[3]);
}
}
}
m_meshCurrent->m_Region = m_regSizeInVoxels;
m_meshCurrent->setOffset(m_regSizeInVoxels.getLowerCorner());
m_meshCurrent->removeUnusedVertices();
m_meshCurrent->m_vecLodRecords.clear();
@ -221,7 +221,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.encodedPosition.setElements(static_cast<uint8_t>(uX), static_cast<uint8_t>(uY), static_cast<uint8_t>(uZ));
cubicVertex.data = uMaterialIn;
rEntry.iIndex = m_meshCurrent->addVertex(cubicVertex);
rEntry.uMaterial = uMaterialIn;

View File

@ -31,9 +31,70 @@ freely, subject to the following restrictions:
#include "PolyVoxCore/BaseVolume.h" //For wrap modes... should move these?
#include "PolyVoxCore/Mesh.h"
#include "PolyVoxCore/DefaultMarchingCubesController.h"
#include "PolyVoxCore/Vertex.h"
namespace PolyVox
{
#ifdef SWIG
struct MarchingCubesVertex
#else
template<typename _DataType>
struct POLYVOX_API MarchingCubesVertex
#endif
{
typedef _DataType DataType;
// Each component of the position is stored using 8.8 fixed-point encoding.
Vector3DUint16 encodedPosition;
// Each component of the normal is encoded using 5 bits of this variable.
// The 16 bits are -xxxxxyyyyyzzzzz (note the left-most bit is currently
// unused). Some extra shifting and scaling is required to make it signed.
uint16_t encodedNormal;
// User data
DataType data;
};
/// Decodes a position from a MarchingCubesVertex
inline Vector3DFloat decode(const Vector3DUint16& encodedPosition)
{
Vector3DFloat result(encodedPosition.getX(), encodedPosition.getY(), encodedPosition.getZ());
result *= (1.0f / 256.0f); // Division is compile-time constant
return result;
}
/// Decodes a normal from a MarchingCubesVertex
inline Vector3DFloat decode(const uint16_t encodedNormal)
{
// Get normal components in the range 0 to 31
uint16_t x = (encodedNormal >> 10) & 0x1F;
uint16_t y = (encodedNormal >> 5) & 0x1F;
uint16_t z = (encodedNormal) & 0x1F;
// Build the resulting vector
Vector3DFloat result(x, y, z);
// Convert to range 0.0 to 2.0
result *= (1.0f / 15.5f); // Division is compile-time constant
// Convert to range -1.0 to 1.0
result -= Vector3DFloat(1.0f, 1.0f, 1.0f);
return result;
}
/// Decodes a MarchingCubesVertex by converting it into a regular Vertex which can then be directly used for rendering.
template<typename DataType>
Vertex<DataType> decode(const MarchingCubesVertex<DataType>& marchingCubesVertex)
{
Vertex<DataType> result;
result.position = decode(marchingCubesVertex.encodedPosition);
result.normal = decode(marchingCubesVertex.encodedNormal);
result.data = marchingCubesVertex.data; // Data is not encoded
return result;
}
template< typename VolumeType, typename Controller = DefaultMarchingCubesController<typename VolumeType::VoxelType> >
class MarchingCubesSurfaceExtractor
{

View File

@ -122,7 +122,7 @@ namespace PolyVox
m_regSliceCurrent.shift(Vector3DInt32(0,0,1));
}
m_meshCurrent->m_Region = m_regSizeInVoxels;
m_meshCurrent->setOffset(m_regSizeInVoxels.getLowerCorner());
m_meshCurrent->m_vecLodRecords.clear();
LodRecord lodRecord;
@ -470,8 +470,8 @@ namespace PolyVox
const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v000, v100, fInterp);
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
surfaceVertex.position = v3dScaledPosition;
surfaceVertex.normal = encodedNormal;
surfaceVertex.encodedPosition = v3dScaledPosition;
surfaceVertex.encodedNormal = encodedNormal;
surfaceVertex.data = uMaterial;
const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
@ -513,8 +513,8 @@ namespace PolyVox
const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v000, v010, fInterp);
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
surfaceVertex.position = v3dScaledPosition;
surfaceVertex.normal = encodedNormal;
surfaceVertex.encodedPosition = v3dScaledPosition;
surfaceVertex.encodedNormal = encodedNormal;
surfaceVertex.data = uMaterial;
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
@ -555,8 +555,8 @@ namespace PolyVox
const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v000, v001, fInterp);
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
surfaceVertex.position = v3dScaledPosition;
surfaceVertex.normal = encodedNormal;
surfaceVertex.encodedPosition = v3dScaledPosition;
surfaceVertex.encodedNormal = encodedNormal;
surfaceVertex.data = uMaterial;
const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);

View File

@ -27,7 +27,7 @@ freely, subject to the following restrictions:
#include "Impl/TypeDef.h"
#include "PolyVoxCore/Region.h"
#include "PolyVoxCore/VertexTypes.h" //Should probably do away with this on in the future...
#include "PolyVoxCore/Vertex.h" //Should probably do away with this on in the future...
#include <algorithm>
#include <cstdlib>
@ -52,54 +52,31 @@ namespace PolyVox
typedef _VertexType VertexType;
Mesh();
~Mesh();
Mesh();
~Mesh();
const std::vector<uint32_t>& getIndices(void) const;
uint32_t getNoOfIndices(void) const;
uint32_t getNoOfNonUniformTrianges(void) const;
uint32_t getNoOfUniformTrianges(void) const;
uint32_t getNoOfVertices(void) const;
std::vector<VertexType>& getRawVertexData(void); //FIXME - this should be removed
const std::vector<VertexType>& getVertices(void) const;
const std::vector<uint32_t>& getIndices(void) const;
uint32_t getNoOfIndices(void) const;
uint32_t getNoOfVertices(void) const;
const std::vector<VertexType>& getVertices(void) const;
const Vector3DInt32& getOffset(void) const;
void addTriangle(uint32_t index0, uint32_t index1, uint32_t index2);
void addTriangleCubic(uint32_t index0, uint32_t index1, uint32_t index2);
uint32_t addVertex(const VertexType& vertex);
void clear(void);
bool isEmpty(void) const;
void setOffset(const Vector3DInt32& offset);
void scaleVertices(float amount);
void translateVertices(const Vector3DFloat& amount);
void addTriangle(uint32_t index0, uint32_t index1, uint32_t index2);
uint32_t addVertex(const VertexType& vertex);
void clear(void);
bool isEmpty(void) const;
void removeUnusedVertices(void);
//THESE FUNCTIONS TO BE REMOVED IN THE FUTURE. OR AT LEAST MOVED OUT OF THIS CLASS INTO FREE FUNCTIONS.
//THEY ARE CAUSING PROBLEMS WITH THE SWIG BINDINGS. THE FUNCTIONS REGARDING NORMALS MAKE NO SENSE WHEN
//A VERTEX MIGHT NOT HAVE NORMALS. THE EXTRACT SUBSET FUNCTION SHOULD MAYBE BE APPLICATION CODE, AT ANY
//RATE THE STD::SET CAUSES PROBLEMS WITH SWIG. IF YOU UNCOMMENT ANY OF THESE FUNCTIONS, PLEASE POST ON
//THE FORUM SO WE CAN KNOW THE FUNCTIONALITY IS STILL NEEDED IN SOME FORM.
//void sumNearbyNormals(bool bNormaliseResult = true);
//std::shared_ptr< Mesh<VertexType> > extractSubset(std::set<uint8_t> setMaterials);
//void generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices = false);
int noOfDegenerateTris(void);
void removeDegenerateTris(void);
void removeUnusedVertices(void);
Region m_Region;
int32_t m_iTimeStamp;
int32_t m_iNoOfLod0Tris;
Vector3DInt32 m_offset;
public:
std::vector<uint32_t> m_vecTriangleIndices;
std::vector<VertexType> m_vecVertices;
std::vector<LodRecord> m_vecLodRecords;
};
template <typename VertexType>
std::shared_ptr< Mesh<VertexType> > extractSubset(Mesh<VertexType>& inputMesh, std::set<uint8_t> setMaterials);
};
template <typename MeshType>
Mesh< Vertex< typename MeshType::VertexType::DataType > > decode(const MeshType& mesh)
@ -114,7 +91,7 @@ namespace PolyVox
result.m_vecTriangleIndices = mesh.m_vecTriangleIndices;
result.m_Region = mesh.m_Region;
result.m_offset = mesh.m_offset;
return result;
}

View File

@ -26,7 +26,6 @@ namespace PolyVox
template <typename VertexType>
Mesh<VertexType>::Mesh()
{
m_iTimeStamp = -1;
}
template <typename VertexType>
@ -44,39 +43,6 @@ namespace PolyVox
uint32_t Mesh<VertexType>::getNoOfIndices(void) const
{
return m_vecTriangleIndices.size();
}
template <typename VertexType>
uint32_t Mesh<VertexType>::getNoOfNonUniformTrianges(void) const
{
uint32_t result = 0;
for(uint32_t i = 0; i < m_vecTriangleIndices.size() - 2; i += 3)
{
if((m_vecVertices[m_vecTriangleIndices[i]].getMaterial() == m_vecVertices[m_vecTriangleIndices[i+1]].getMaterial())
&& (m_vecVertices[m_vecTriangleIndices[i]].getMaterial() == m_vecVertices[m_vecTriangleIndices[i+2]].getMaterial()))
{
}
else
{
result++;
}
}
return result;
}
template <typename VertexType>
uint32_t Mesh<VertexType>::getNoOfUniformTrianges(void) const
{
uint32_t result = 0;
for(uint32_t i = 0; i < m_vecTriangleIndices.size() - 2; i += 3)
{
if((m_vecVertices[m_vecTriangleIndices[i]].getMaterial() == m_vecVertices[m_vecTriangleIndices[i+1]].getMaterial())
&& (m_vecVertices[m_vecTriangleIndices[i]].getMaterial() == m_vecVertices[m_vecTriangleIndices[i+2]].getMaterial()))
{
result++;
}
}
return result;
}
template <typename VertexType>
@ -85,33 +51,26 @@ namespace PolyVox
return m_vecVertices.size();
}
template <typename VertexType>
std::vector<VertexType>& Mesh<VertexType>::getRawVertexData(void)
{
return m_vecVertices;
}
template <typename VertexType>
const std::vector<VertexType>& Mesh<VertexType>::getVertices(void) const
{
return m_vecVertices;
}
template <typename VertexType>
void Mesh<VertexType>::addTriangle(uint32_t index0, uint32_t index1, uint32_t index2)
{
//Make sure the specified indices correspond to valid vertices.
POLYVOX_ASSERT(index0 < m_vecVertices.size(), "Index points at an invalid vertex.");
POLYVOX_ASSERT(index1 < m_vecVertices.size(), "Index points at an invalid vertex.");
POLYVOX_ASSERT(index2 < m_vecVertices.size(), "Index points at an invalid vertex.");
m_vecTriangleIndices.push_back(index0);
m_vecTriangleIndices.push_back(index1);
m_vecTriangleIndices.push_back(index2);
}
template <typename VertexType>
void Mesh<VertexType>::addTriangleCubic(uint32_t index0, uint32_t index1, uint32_t index2)
const Vector3DInt32& Mesh<VertexType>::getOffset(void) const
{
return m_offset;
}
template <typename VertexType>
void Mesh<VertexType>::setOffset(const Vector3DInt32& offset)
{
m_offset = offset;
}
template <typename VertexType>
void Mesh<VertexType>::addTriangle(uint32_t index0, uint32_t index1, uint32_t index2)
{
//Make sure the specified indices correspond to valid vertices.
POLYVOX_ASSERT(index0 < m_vecVertices.size(), "Index points at an invalid vertex.");
@ -135,7 +94,6 @@ namespace PolyVox
{
m_vecVertices.clear();
m_vecTriangleIndices.clear();
m_vecLodRecords.clear();
}
template <typename VertexType>
@ -144,223 +102,6 @@ namespace PolyVox
return (getNoOfVertices() == 0) || (getNoOfIndices() == 0);
}
////////////////////////////////////////////////////////////////////////////////
/// This function can help improve the visual appearance of a surface patch by
/// smoothing normals with other nearby normals. It iterates over each triangle
/// in the surface patch and determines the sum of its corners normals. For any
/// given vertex, these sums are in turn summed for any triangles which use the
/// vertex. Usually, the resulting normals should be renormalised afterwards.
/// Note: This function can cause lighting discontinuities accross region boundaries.
////////////////////////////////////////////////////////////////////////////////
/*template <typename VertexType>
void Mesh<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...
{
return;
}
std::vector<Vector3DFloat> summedNormals(m_vecVertices.size());
//Initialise all normals to zero. Should be ok as the vector should store all elements contiguously.
memset(&summedNormals[0], 0, summedNormals.size() * sizeof(Vector3DFloat));
for(vector<uint32_t>::iterator iterIndex = m_vecTriangleIndices.begin(); iterIndex != m_vecTriangleIndices.end();)
{
PositionMaterialNormal& v0 = m_vecVertices[*iterIndex];
Vector3DFloat& v0New = summedNormals[*iterIndex];
iterIndex++;
PositionMaterialNormal& v1 = m_vecVertices[*iterIndex];
Vector3DFloat& v1New = summedNormals[*iterIndex];
iterIndex++;
PositionMaterialNormal& v2 = m_vecVertices[*iterIndex];
Vector3DFloat& v2New = summedNormals[*iterIndex];
iterIndex++;
Vector3DFloat sumOfNormals = v0.getNormal() + v1.getNormal() + v2.getNormal();
v0New += sumOfNormals;
v1New += sumOfNormals;
v2New += sumOfNormals;
}
for(uint32_t uIndex = 0; uIndex < summedNormals.size(); uIndex++)
{
if(bNormaliseResult)
{
summedNormals[uIndex].normalise();
}
m_vecVertices[uIndex].setNormal(summedNormals[uIndex]);
}
}*/
/*template <typename VertexType>
void Mesh<VertexType>::generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices)
{
Vector3DFloat offset = static_cast<Vector3DFloat>(m_Region.getLowerCorner());
//Initially zero the normals
for(vector<PositionMaterialNormal>::iterator iterVertex = m_vecVertices.begin(); iterVertex != m_vecVertices.end(); iterVertex++)
{
if(m_Region.containsPoint(iterVertex->getPosition() + offset, 0.001))
{
iterVertex->setNormal(Vector3DFloat(0.0f,0.0f,0.0f));
}
}
for(vector<uint32_t>::iterator iterIndex = m_vecTriangleIndices.begin(); iterIndex != m_vecTriangleIndices.end();)
{
PositionMaterialNormal& v0 = m_vecVertices[*iterIndex];
iterIndex++;
PositionMaterialNormal& v1 = m_vecVertices[*iterIndex];
iterIndex++;
PositionMaterialNormal& v2 = m_vecVertices[*iterIndex];
iterIndex++;
Vector3DFloat triangleNormal = (v1.getPosition()-v0.getPosition()).cross(v2.getPosition()-v0.getPosition());
if(m_Region.containsPoint(v0.getPosition() + offset, 0.001))
{
v0.setNormal(v0.getNormal() + triangleNormal);
}
if(m_Region.containsPoint(v1.getPosition() + offset, 0.001))
{
v1.setNormal(v1.getNormal() + triangleNormal);
}
if(m_Region.containsPoint(v2.getPosition() + offset, 0.001))
{
v2.setNormal(v2.getNormal() + triangleNormal);
}
}
if(bNormalise)
{
for(vector<PositionMaterialNormal>::iterator iterVertex = m_vecVertices.begin(); iterVertex != m_vecVertices.end(); iterVertex++)
{
Vector3DFloat normal = iterVertex->getNormal();
normal.normalise();
iterVertex->setNormal(normal);
}
}
}*/
/*template <typename VertexType>
std::shared_ptr< Mesh<VertexType> > Mesh<VertexType>::extractSubset(std::set<uint8_t> setMaterials)
{
std::shared_ptr< Mesh<VertexType> > result(new Mesh<VertexType>);
if(m_vecVertices.size() == 0) //FIXME - I don't think we should need this test, but I have seen crashes otherwise...
{
return result;
}
assert(m_vecLodRecords.size() == 1);
if(m_vecLodRecords.size() != 1)
{
//If we have done progressive LOD then it's too late to split into subsets.
return result;
}
std::vector<int32_t> indexMap(m_vecVertices.size());
std::fill(indexMap.begin(), indexMap.end(), -1);
for(uint32_t triCt = 0; triCt < m_vecTriangleIndices.size(); triCt += 3)
{
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()) ||
(setMaterials.find(v1.getMaterial()) != setMaterials.end()) ||
(setMaterials.find(v2.getMaterial()) != setMaterials.end()))
{
uint32_t i0;
if(indexMap[m_vecTriangleIndices[triCt]] == -1)
{
indexMap[m_vecTriangleIndices[triCt]] = result->addVertex(v0);
}
i0 = indexMap[m_vecTriangleIndices[triCt]];
uint32_t i1;
if(indexMap[m_vecTriangleIndices[triCt+1]] == -1)
{
indexMap[m_vecTriangleIndices[triCt+1]] = result->addVertex(v1);
}
i1 = indexMap[m_vecTriangleIndices[triCt+1]];
uint32_t i2;
if(indexMap[m_vecTriangleIndices[triCt+2]] == -1)
{
indexMap[m_vecTriangleIndices[triCt+2]] = result->addVertex(v2);
}
i2 = indexMap[m_vecTriangleIndices[triCt+2]];
result->addTriangle(i0,i1,i2);
}
}
result->m_vecLodRecords.clear();
LodRecord lodRecord;
lodRecord.beginIndex = 0;
lodRecord.endIndex = result->getNoOfIndices();
result->m_vecLodRecords.push_back(lodRecord);
return result;
}*/
template <typename VertexType>
int Mesh<VertexType>::noOfDegenerateTris(void)
{
int count = 0;
for(uint32_t triCt = 0; triCt < m_vecTriangleIndices.size();)
{
int v0 = m_vecTriangleIndices[triCt];
triCt++;
int v1 = m_vecTriangleIndices[triCt];
triCt++;
int v2 = m_vecTriangleIndices[triCt];
triCt++;
if((v0 == v1) || (v1 == v2) || (v2 == v0))
{
count++;
}
}
return count;
}
template <typename VertexType>
void Mesh<VertexType>::removeDegenerateTris(void)
{
int noOfNonDegenerate = 0;
int targetCt = 0;
for(uint32_t triCt = 0; triCt < m_vecTriangleIndices.size();)
{
int v0 = m_vecTriangleIndices[triCt];
triCt++;
int v1 = m_vecTriangleIndices[triCt];
triCt++;
int v2 = m_vecTriangleIndices[triCt];
triCt++;
if((v0 != v1) && (v1 != v2) & (v2 != v0))
{
m_vecTriangleIndices[targetCt] = v0;
targetCt++;
m_vecTriangleIndices[targetCt] = v1;
targetCt++;
m_vecTriangleIndices[targetCt] = v2;
targetCt++;
noOfNonDegenerate++;
}
}
m_vecTriangleIndices.resize(noOfNonDegenerate * 3);
}
template <typename VertexType>
void Mesh<VertexType>::removeUnusedVertices(void)
{
@ -392,97 +133,4 @@ namespace PolyVox
m_vecTriangleIndices[triCt] = newPos[m_vecTriangleIndices[triCt]];
}
}
//Currently a free function - think where this needs to go.
template <typename VertexType>
std::shared_ptr< Mesh<VertexType> > extractSubset(Mesh<VertexType>& inputMesh, std::set<uint8_t> setMaterials)
{
std::shared_ptr< Mesh<VertexType> > result(new Mesh<VertexType>);
result->m_Region = inputMesh.m_Region;
if(inputMesh.m_vecVertices.size() == 0) //FIXME - I don't think we should need this test, but I have seen crashes otherwise...
{
return result;
}
POLYVOX_ASSERT(inputMesh.m_vecLodRecords.size() == 1, "Number of LOD records must equal one.");
if(inputMesh.m_vecLodRecords.size() != 1)
{
//If we have done progressive LOD then it's too late to split into subsets.
return result;
}
std::vector<int32_t> indexMap(inputMesh.m_vecVertices.size());
std::fill(indexMap.begin(), indexMap.end(), -1);
for(uint32_t triCt = 0; triCt < inputMesh.m_vecTriangleIndices.size(); triCt += 3)
{
VertexType& v0 = inputMesh.m_vecVertices[inputMesh.m_vecTriangleIndices[triCt]];
VertexType& v1 = inputMesh.m_vecVertices[inputMesh.m_vecTriangleIndices[triCt + 1]];
VertexType& v2 = inputMesh.m_vecVertices[inputMesh.m_vecTriangleIndices[triCt + 2]];
if(
(setMaterials.find(v0.getMaterial()) != setMaterials.end()) ||
(setMaterials.find(v1.getMaterial()) != setMaterials.end()) ||
(setMaterials.find(v2.getMaterial()) != setMaterials.end()))
{
uint32_t i0;
if(indexMap[inputMesh.m_vecTriangleIndices[triCt]] == -1)
{
indexMap[inputMesh.m_vecTriangleIndices[triCt]] = result->addVertex(v0);
}
i0 = indexMap[inputMesh.m_vecTriangleIndices[triCt]];
uint32_t i1;
if(indexMap[inputMesh.m_vecTriangleIndices[triCt+1]] == -1)
{
indexMap[inputMesh.m_vecTriangleIndices[triCt+1]] = result->addVertex(v1);
}
i1 = indexMap[inputMesh.m_vecTriangleIndices[triCt+1]];
uint32_t i2;
if(indexMap[inputMesh.m_vecTriangleIndices[triCt+2]] == -1)
{
indexMap[inputMesh.m_vecTriangleIndices[triCt+2]] = result->addVertex(v2);
}
i2 = indexMap[inputMesh.m_vecTriangleIndices[triCt+2]];
result->addTriangle(i0,i1,i2);
}
}
result->m_vecLodRecords.clear();
LodRecord lodRecord;
lodRecord.beginIndex = 0;
lodRecord.endIndex = result->getNoOfIndices();
result->m_vecLodRecords.push_back(lodRecord);
return result;
}
template <typename VertexType>
void Mesh<VertexType>::scaleVertices(float amount)
{
for(uint32_t ct = 0; ct < m_vecVertices.size(); ct++)
{
//TODO: Should rethink accessors here to provide faster access
Vector3DFloat position = m_vecVertices[ct].getPosition();
position *= amount;
m_vecVertices[ct].setPosition(position);
}
}
template <typename VertexType>
void Mesh<VertexType>::translateVertices(const Vector3DFloat& amount)
{
for(uint32_t ct = 0; ct < m_vecVertices.size(); ct++)
{
//TODO: Should rethink accessors here to provide faster access
Vector3DFloat position = m_vecVertices[ct].getPosition();
position += amount;
m_vecVertices[ct].setPosition(position);
}
}
}

View File

@ -0,0 +1,51 @@
/*******************************************************************************
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_Vertex_H__
#define __PolyVox_Vertex_H__
#include "Impl/TypeDef.h"
#include "PolyVoxCore/Vector.h"
#include <bitset>
#include <vector>
namespace PolyVox
{
#ifdef SWIG
struct Vertex
#else
template<typename _DataType>
struct POLYVOX_API Vertex
#endif
{
typedef _DataType DataType;
Vector3DFloat position;
Vector3DFloat normal;
DataType data;
};
}
#endif // __PolyVox_Vertex_H__

View File

@ -1,112 +0,0 @@
/*******************************************************************************
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_SurfaceVertex_H__
#define __PolyVox_SurfaceVertex_H__
#include "Impl/TypeDef.h"
#include "PolyVoxCore/Vector.h"
#include <bitset>
#include <vector>
namespace PolyVox
{
#ifdef SWIG
struct Vertex
#else
template<typename _DataType>
struct POLYVOX_API Vertex
#endif
{
typedef _DataType DataType;
Vector3DFloat position;
Vector3DFloat normal;
DataType data;
};
#ifdef SWIG
struct CubicVertex
#else
template<typename _DataType>
struct POLYVOX_API CubicVertex
#endif
{
typedef _DataType DataType;
Vector3DUint8 position;
uint8_t normal;
DataType data;
};
#ifdef SWIG
struct MarchingCubesVertex
#else
template<typename _DataType>
struct POLYVOX_API MarchingCubesVertex
#endif
{
typedef _DataType DataType;
Vector3DUint16 position;
uint16_t normal;
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 DataType>
Vertex<DataType> decode(const CubicVertex<DataType>& cubicVertex)
{
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.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 DataType>
Vertex<DataType> decode(const MarchingCubesVertex<DataType>& marchingCubesVertex)
{
Vertex<DataType> result;
result.position = Vector3DFloat(marchingCubesVertex.position.getX(), marchingCubesVertex.position.getY(), marchingCubesVertex.position.getZ());
result.position *= (1.0 / 256.0);
uint16_t encodedX = (marchingCubesVertex.normal >> 10) & 0x1F;
uint16_t encodedY = (marchingCubesVertex.normal >> 5) & 0x1F;
uint16_t encodedZ = (marchingCubesVertex.normal) & 0x1F;
result.normal = Vector3DFloat(encodedX, encodedY, encodedZ);
result.normal /= 15.5f;
result.normal -= Vector3DFloat(1.0f, 1.0f, 1.0f);
result.data = marchingCubesVertex.data;
return result;
}
}
#endif

View File

@ -1 +0,0 @@