diff --git a/demo/main.cpp b/demo/main.cpp index 677e31b0a12557c49753896223570d98a77478a8..f38b2c15bbe499dfeff7f288d5e7c126c03bead4 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -107,6 +107,7 @@ int main(int argc, char* argv[]) { fggl::data::make_slope( mesh, rightSlope ); } + mesh.removeDups(); auto token = meshRenderer.upload( mesh ); token.pipeline = shaderPhong; ecs.addComponent<fggl::gfx::MeshToken>(entity, token); diff --git a/fggl/data/model.cpp b/fggl/data/model.cpp index e57c5c8a931421241070d22b4e6292bf921547a5..b6cb8e6462e8aa03fd8ada265627ece62faf00da 100644 --- a/fggl/data/model.cpp +++ b/fggl/data/model.cpp @@ -1,5 +1,8 @@ #include <fggl/data/model.hpp> +#include <map> +#include <stdexcept> + using namespace fggl::data; Mesh::Mesh() : m_verts(), m_index() { @@ -27,6 +30,46 @@ int Mesh::indexOf(Vertex vert) { return -1; } +void Mesh::removeDups() { + // lookups to make detecting duplicates easier + std::map<Vertex, unsigned int> mapping; + unsigned int nextID = 0; + + // new data + std::vector< Vertex > newVerts; + std::vector< unsigned int > newIndexes; + newIndexes.reserve( m_index.size() ); // newIndex will be same size as oldIndex + + for ( auto& idx : m_index ) { + auto& vertex = m_verts[idx]; + auto newID = nextID; + try { + newID = mapping.at( vertex ); + } catch ( std::out_of_range& e ){ + mapping[ vertex ] = newID; + newVerts.push_back( vertex ); + ++nextID; + } + newIndexes.push_back( newID ); + } + + // FIXME must be faster way to do this... + m_verts.clear(); + m_index.clear(); + + for ( auto& vert : newVerts ) { + m_verts.push_back( vert ); + } + + for ( auto& idx : newIndexes ) { + m_index.push_back( idx ); + } + + // ensure we're not wasting space + m_verts.shrink_to_fit(); + m_index.shrink_to_fit(); +} + Model::Model() { } diff --git a/fggl/data/model.hpp b/fggl/data/model.hpp index ed67945573124eba2bebcbf9667168e7612eacbe..2f57d00b9def77166f3a3cd60ad8ca71770d6a18 100644 --- a/fggl/data/model.hpp +++ b/fggl/data/model.hpp @@ -1,6 +1,7 @@ #ifndef FGGL_DATA_MODEL_H #define FGGL_DATA_MODEL_H +#include <tuple> #include <vector> #include <fggl/math/types.hpp> @@ -12,6 +13,23 @@ namespace fggl::data { math::vec3 colour; }; + // comparison operators + + inline bool operator<(const Vertex& lhs, const Vertex& rhs) { + return std::tie( lhs.posititon, lhs.normal, lhs.colour ) + < std::tie( rhs.posititon, rhs.normal, rhs.colour ); + } + + inline bool operator==(const Vertex& lhs, const Vertex& rhs) { + return lhs.posititon == rhs.posititon + && lhs.colour == rhs.colour + && lhs.normal == rhs.normal; + } + + inline bool operator!=(const Vertex& lhs, const Vertex& rhs) { + return !(lhs==rhs); + } + class Mesh { public: Mesh(); @@ -45,6 +63,13 @@ namespace fggl::data { */ unsigned int pushVertex(Vertex vert); + /** + * remove Duplicate verticies + * + * If generated using the procedural system, the mesh data can get a little messy. + * This method will remove unused and duplicate verticies. + */ + void removeDups(); /** * Search for a vertex. diff --git a/fggl/math/types.hpp b/fggl/math/types.hpp index 32d45d308031d4d1b22fb0d4eeca3d68f0d382f3..e4b3c4612651aef354fd78c2446cc701cdbf2a15 100644 --- a/fggl/math/types.hpp +++ b/fggl/math/types.hpp @@ -1,6 +1,8 @@ #ifndef FGGL_MATH_TYPES_H #define FGGL_MATH_TYPES_H +#include <tuple> + #include <glm/ext/matrix_transform.hpp> #include <glm/glm.hpp> #include <glm/gtc/quaternion.hpp> @@ -15,6 +17,7 @@ namespace fggl::math { using mat4 = glm::mat4; using quat = glm::quat; + // reference vectors constexpr vec3 UP { 0.0f, 1.0f, 0.0f }; constexpr vec3 FORWARD { 1.0f, 0.0f, 0.0f }; @@ -98,4 +101,14 @@ namespace fggl::math { } + +// feels a bit strange to be doing this... +namespace glm { + inline bool operator<(const vec3& lhs, const vec3& rhs) { + return std::tie( lhs.x, lhs.y, lhs.z ) + < std::tie( rhs.x, rhs.y, rhs.z ); + } +} + + #endif