Merge branch 'feature/vertex-and-example-refactor' of https://bitbucket.org/volumesoffun/polyvox into feature/vertex-and-example-refactor
This commit is contained in:
commit
e6dc0716cd
@ -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
|
// 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
|
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
|
// 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
|
// 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
|
// 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.
|
// chosen surface extractor generates normals and can skip uploading them if not.
|
||||||
glEnableVertexAttribArray(1); // Attrib '1' is the vertex normals.
|
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
|
// 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.
|
// 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.
|
||||||
|
@ -130,8 +130,9 @@ int main(int argc, char *argv[])
|
|||||||
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
|
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
|
||||||
auto decodedMesh = decode(mesh);
|
auto decodedMesh = decode(mesh);
|
||||||
|
|
||||||
//Pass the surface to the OpenGL window
|
// Pass the surface to the OpenGL window. Note that we are also passing an offset in this multi-mesh example. This is because
|
||||||
openGLWidget.addMesh(decodedMesh, Vector3DInt32(x, y, z));
|
// the surface extractors return a mesh with 'local space' positions to reduce storage requirements and precision problems.
|
||||||
|
openGLWidget.addMesh(decodedMesh, decodedMesh.getOffset());
|
||||||
|
|
||||||
meshCounter++;
|
meshCounter++;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ public:
|
|||||||
// The GL_ARRAY_BUFFER will contain the list of vertex positions
|
// The GL_ARRAY_BUFFER will contain the list of vertex positions
|
||||||
glGenBuffers(1, &(meshData.vertexBuffer));
|
glGenBuffers(1, &(meshData.vertexBuffer));
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 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
|
// and GL_ELEMENT_ARRAY_BUFFER will contain the indices
|
||||||
glGenBuffers(1, &(meshData.indexBuffer));
|
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
|
// 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
|
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
|
// 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
|
// 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
|
// 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.
|
// chosen surface extractor generates normals and can skip uploading them if not.
|
||||||
glEnableVertexAttribArray(1); // Attrib '1' is the vertex normals.
|
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
|
// 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.
|
// 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'
|
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)
|
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.
|
// We're done uploading and can now unbind.
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
@ -27,7 +27,6 @@ SET(CORE_SRC_FILES
|
|||||||
source/ArraySizes.cpp
|
source/ArraySizes.cpp
|
||||||
source/AStarPathfinder.cpp
|
source/AStarPathfinder.cpp
|
||||||
source/Region.cpp
|
source/Region.cpp
|
||||||
source/VertexTypes.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#Projects headers files
|
#Projects headers files
|
||||||
@ -66,6 +65,8 @@ SET(CORE_INC_FILES
|
|||||||
include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl
|
include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl
|
||||||
include/PolyVoxCore/Material.h
|
include/PolyVoxCore/Material.h
|
||||||
include/PolyVoxCore/MaterialDensityPair.h
|
include/PolyVoxCore/MaterialDensityPair.h
|
||||||
|
include/PolyVoxCore/Mesh.h
|
||||||
|
include/PolyVoxCore/Mesh.inl
|
||||||
include/PolyVoxCore/MinizBlockCompressor.h
|
include/PolyVoxCore/MinizBlockCompressor.h
|
||||||
include/PolyVoxCore/MinizBlockCompressor.inl
|
include/PolyVoxCore/MinizBlockCompressor.inl
|
||||||
include/PolyVoxCore/Pager.h
|
include/PolyVoxCore/Pager.h
|
||||||
@ -84,13 +85,11 @@ SET(CORE_INC_FILES
|
|||||||
include/PolyVoxCore/SimpleVolume.inl
|
include/PolyVoxCore/SimpleVolume.inl
|
||||||
include/PolyVoxCore/SimpleVolumeBlock.inl
|
include/PolyVoxCore/SimpleVolumeBlock.inl
|
||||||
include/PolyVoxCore/SimpleVolumeSampler.inl
|
include/PolyVoxCore/SimpleVolumeSampler.inl
|
||||||
include/PolyVoxCore/Mesh.h
|
|
||||||
include/PolyVoxCore/Mesh.inl
|
|
||||||
include/PolyVoxCore/UncompressedBlock.h
|
include/PolyVoxCore/UncompressedBlock.h
|
||||||
include/PolyVoxCore/UncompressedBlock.inl
|
include/PolyVoxCore/UncompressedBlock.inl
|
||||||
include/PolyVoxCore/Vector.h
|
include/PolyVoxCore/Vector.h
|
||||||
include/PolyVoxCore/Vector.inl
|
include/PolyVoxCore/Vector.inl
|
||||||
include/PolyVoxCore/VertexTypes.h
|
include/PolyVoxCore/Vertex.h
|
||||||
include/PolyVoxCore/VolumeResampler.h
|
include/PolyVoxCore/VolumeResampler.h
|
||||||
include/PolyVoxCore/VolumeResampler.inl
|
include/PolyVoxCore/VolumeResampler.inl
|
||||||
include/PolyVoxCore/VoxelFilters.h
|
include/PolyVoxCore/VoxelFilters.h
|
||||||
|
@ -32,9 +32,46 @@ freely, subject to the following restrictions:
|
|||||||
#include "PolyVoxCore/BaseVolume.h" //For wrap modes... should move these?
|
#include "PolyVoxCore/BaseVolume.h" //For wrap modes... should move these?
|
||||||
#include "PolyVoxCore/DefaultIsQuadNeeded.h"
|
#include "PolyVoxCore/DefaultIsQuadNeeded.h"
|
||||||
#include "PolyVoxCore/Mesh.h"
|
#include "PolyVoxCore/Mesh.h"
|
||||||
|
#include "PolyVoxCore/Vertex.h"
|
||||||
|
|
||||||
namespace PolyVox
|
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
|
/// The CubicSurfaceExtractor creates a mesh in which each voxel appears to be rendered as a cube
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Introduction
|
/// Introduction
|
||||||
|
@ -190,13 +190,13 @@ namespace PolyVox
|
|||||||
for(typename std::list<Quad>::iterator quadIter = listQuads.begin(); quadIter != iterEnd; quadIter++)
|
for(typename std::list<Quad>::iterator quadIter = listQuads.begin(); quadIter != iterEnd; quadIter++)
|
||||||
{
|
{
|
||||||
Quad& quad = *quadIter;
|
Quad& quad = *quadIter;
|
||||||
m_meshCurrent->addTriangleCubic(quad.vertices[0], quad.vertices[1],quad.vertices[2]);
|
m_meshCurrent->addTriangle(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[2],quad.vertices[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_meshCurrent->m_Region = m_regSizeInVoxels;
|
m_meshCurrent->setOffset(m_regSizeInVoxels.getLowerCorner());
|
||||||
m_meshCurrent->removeUnusedVertices();
|
m_meshCurrent->removeUnusedVertices();
|
||||||
|
|
||||||
m_meshCurrent->m_vecLodRecords.clear();
|
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.
|
//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<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;
|
cubicVertex.data = uMaterialIn;
|
||||||
rEntry.iIndex = m_meshCurrent->addVertex(cubicVertex);
|
rEntry.iIndex = m_meshCurrent->addVertex(cubicVertex);
|
||||||
rEntry.uMaterial = uMaterialIn;
|
rEntry.uMaterial = uMaterialIn;
|
||||||
|
@ -31,9 +31,70 @@ freely, subject to the following restrictions:
|
|||||||
#include "PolyVoxCore/BaseVolume.h" //For wrap modes... should move these?
|
#include "PolyVoxCore/BaseVolume.h" //For wrap modes... should move these?
|
||||||
#include "PolyVoxCore/Mesh.h"
|
#include "PolyVoxCore/Mesh.h"
|
||||||
#include "PolyVoxCore/DefaultMarchingCubesController.h"
|
#include "PolyVoxCore/DefaultMarchingCubesController.h"
|
||||||
|
#include "PolyVoxCore/Vertex.h"
|
||||||
|
|
||||||
namespace PolyVox
|
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> >
|
template< typename VolumeType, typename Controller = DefaultMarchingCubesController<typename VolumeType::VoxelType> >
|
||||||
class MarchingCubesSurfaceExtractor
|
class MarchingCubesSurfaceExtractor
|
||||||
{
|
{
|
||||||
|
@ -122,7 +122,7 @@ namespace PolyVox
|
|||||||
m_regSliceCurrent.shift(Vector3DInt32(0,0,1));
|
m_regSliceCurrent.shift(Vector3DInt32(0,0,1));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_meshCurrent->m_Region = m_regSizeInVoxels;
|
m_meshCurrent->setOffset(m_regSizeInVoxels.getLowerCorner());
|
||||||
|
|
||||||
m_meshCurrent->m_vecLodRecords.clear();
|
m_meshCurrent->m_vecLodRecords.clear();
|
||||||
LodRecord lodRecord;
|
LodRecord lodRecord;
|
||||||
@ -470,8 +470,8 @@ namespace PolyVox
|
|||||||
const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v000, v100, fInterp);
|
const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v000, v100, fInterp);
|
||||||
|
|
||||||
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
|
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
|
||||||
surfaceVertex.position = v3dScaledPosition;
|
surfaceVertex.encodedPosition = v3dScaledPosition;
|
||||||
surfaceVertex.normal = encodedNormal;
|
surfaceVertex.encodedNormal = encodedNormal;
|
||||||
surfaceVertex.data = uMaterial;
|
surfaceVertex.data = uMaterial;
|
||||||
|
|
||||||
const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
|
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);
|
const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v000, v010, fInterp);
|
||||||
|
|
||||||
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
|
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
|
||||||
surfaceVertex.position = v3dScaledPosition;
|
surfaceVertex.encodedPosition = v3dScaledPosition;
|
||||||
surfaceVertex.normal = encodedNormal;
|
surfaceVertex.encodedNormal = encodedNormal;
|
||||||
surfaceVertex.data = uMaterial;
|
surfaceVertex.data = uMaterial;
|
||||||
|
|
||||||
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
|
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
|
||||||
@ -555,8 +555,8 @@ namespace PolyVox
|
|||||||
const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v000, v001, fInterp);
|
const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v000, v001, fInterp);
|
||||||
|
|
||||||
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
|
MarchingCubesVertex<typename VolumeType::VoxelType> surfaceVertex;
|
||||||
surfaceVertex.position = v3dScaledPosition;
|
surfaceVertex.encodedPosition = v3dScaledPosition;
|
||||||
surfaceVertex.normal = encodedNormal;
|
surfaceVertex.encodedNormal = encodedNormal;
|
||||||
surfaceVertex.data = uMaterial;
|
surfaceVertex.data = uMaterial;
|
||||||
|
|
||||||
const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
|
const uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
|
||||||
|
@ -27,7 +27,7 @@ freely, subject to the following restrictions:
|
|||||||
#include "Impl/TypeDef.h"
|
#include "Impl/TypeDef.h"
|
||||||
|
|
||||||
#include "PolyVoxCore/Region.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 <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -52,54 +52,31 @@ namespace PolyVox
|
|||||||
|
|
||||||
typedef _VertexType VertexType;
|
typedef _VertexType VertexType;
|
||||||
|
|
||||||
Mesh();
|
Mesh();
|
||||||
~Mesh();
|
~Mesh();
|
||||||
|
|
||||||
const std::vector<uint32_t>& getIndices(void) const;
|
const std::vector<uint32_t>& getIndices(void) const;
|
||||||
uint32_t getNoOfIndices(void) const;
|
uint32_t getNoOfIndices(void) const;
|
||||||
uint32_t getNoOfNonUniformTrianges(void) const;
|
uint32_t getNoOfVertices(void) const;
|
||||||
uint32_t getNoOfUniformTrianges(void) const;
|
const std::vector<VertexType>& getVertices(void) const;
|
||||||
uint32_t getNoOfVertices(void) const;
|
const Vector3DInt32& getOffset(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);
|
void setOffset(const Vector3DInt32& offset);
|
||||||
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 scaleVertices(float amount);
|
void addTriangle(uint32_t index0, uint32_t index1, uint32_t index2);
|
||||||
void translateVertices(const Vector3DFloat& amount);
|
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.
|
Vector3DInt32 m_offset;
|
||||||
//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;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<uint32_t> m_vecTriangleIndices;
|
std::vector<uint32_t> m_vecTriangleIndices;
|
||||||
std::vector<VertexType> m_vecVertices;
|
std::vector<VertexType> m_vecVertices;
|
||||||
|
|
||||||
std::vector<LodRecord> m_vecLodRecords;
|
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>
|
template <typename MeshType>
|
||||||
Mesh< Vertex< typename MeshType::VertexType::DataType > > decode(const MeshType& mesh)
|
Mesh< Vertex< typename MeshType::VertexType::DataType > > decode(const MeshType& mesh)
|
||||||
@ -114,7 +91,7 @@ namespace PolyVox
|
|||||||
|
|
||||||
result.m_vecTriangleIndices = mesh.m_vecTriangleIndices;
|
result.m_vecTriangleIndices = mesh.m_vecTriangleIndices;
|
||||||
|
|
||||||
result.m_Region = mesh.m_Region;
|
result.m_offset = mesh.m_offset;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ namespace PolyVox
|
|||||||
template <typename VertexType>
|
template <typename VertexType>
|
||||||
Mesh<VertexType>::Mesh()
|
Mesh<VertexType>::Mesh()
|
||||||
{
|
{
|
||||||
m_iTimeStamp = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VertexType>
|
template <typename VertexType>
|
||||||
@ -44,39 +43,6 @@ namespace PolyVox
|
|||||||
uint32_t Mesh<VertexType>::getNoOfIndices(void) const
|
uint32_t Mesh<VertexType>::getNoOfIndices(void) const
|
||||||
{
|
{
|
||||||
return m_vecTriangleIndices.size();
|
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>
|
template <typename VertexType>
|
||||||
@ -85,33 +51,26 @@ namespace PolyVox
|
|||||||
return m_vecVertices.size();
|
return m_vecVertices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VertexType>
|
|
||||||
std::vector<VertexType>& Mesh<VertexType>::getRawVertexData(void)
|
|
||||||
{
|
|
||||||
return m_vecVertices;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename VertexType>
|
template <typename VertexType>
|
||||||
const std::vector<VertexType>& Mesh<VertexType>::getVertices(void) const
|
const std::vector<VertexType>& Mesh<VertexType>::getVertices(void) const
|
||||||
{
|
{
|
||||||
return m_vecVertices;
|
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>
|
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.
|
//Make sure the specified indices correspond to valid vertices.
|
||||||
POLYVOX_ASSERT(index0 < m_vecVertices.size(), "Index points at an invalid vertex.");
|
POLYVOX_ASSERT(index0 < m_vecVertices.size(), "Index points at an invalid vertex.");
|
||||||
@ -135,7 +94,6 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
m_vecVertices.clear();
|
m_vecVertices.clear();
|
||||||
m_vecTriangleIndices.clear();
|
m_vecTriangleIndices.clear();
|
||||||
m_vecLodRecords.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VertexType>
|
template <typename VertexType>
|
||||||
@ -144,223 +102,6 @@ namespace PolyVox
|
|||||||
return (getNoOfVertices() == 0) || (getNoOfIndices() == 0);
|
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>
|
template <typename VertexType>
|
||||||
void Mesh<VertexType>::removeUnusedVertices(void)
|
void Mesh<VertexType>::removeUnusedVertices(void)
|
||||||
{
|
{
|
||||||
@ -392,97 +133,4 @@ namespace PolyVox
|
|||||||
m_vecTriangleIndices[triCt] = newPos[m_vecTriangleIndices[triCt]];
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
51
library/PolyVoxCore/include/PolyVoxCore/Vertex.h
Normal file
51
library/PolyVoxCore/include/PolyVoxCore/Vertex.h
Normal 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__
|
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
|
|
Loading…
x
Reference in New Issue
Block a user