Restore merging of near-identical vertices for JoinIdenticalVertices (#6278)
* Restore merging of near-identical vertices for JoinIdenticalVertices --------- Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
This commit is contained in:
@@ -100,6 +100,65 @@ void JoinVerticesProcess::Execute( aiScene* pScene) {
|
||||
|
||||
namespace {
|
||||
|
||||
struct CompareVerticesAlmostEqual {
|
||||
bool operator () (const Vertex & a, const Vertex & b) const {
|
||||
static const float epsilon = 1e-5f;
|
||||
static const float squareEpsilon = epsilon * epsilon;
|
||||
|
||||
if ((a.position - b.position).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We just test the other attributes even if they're not present in the mesh.
|
||||
// In this case they're initialized to 0 so the comparison succeeds.
|
||||
// By this method the non-present attributes are effectively ignored in the comparison.
|
||||
|
||||
if ((a.normal - b.normal).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a.tangent - b.tangent).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a.bitangent - b.bitangent).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i ++) {
|
||||
if ((a.texcoords[i] - b.texcoords[i]).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; i ++) {
|
||||
if (GetColorDifference(a.colors[i], b.colors[i]) > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If reached this point, they are ~equal
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct HashVertex {
|
||||
inline void hash_combine(std::size_t& seed, const ai_real& v) const {
|
||||
std::hash<ai_real> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
size_t operator () (const Vertex & v) const {
|
||||
size_t hash = 0;
|
||||
|
||||
hash_combine(hash, v.position.x);
|
||||
hash_combine(hash, v.position.y);
|
||||
hash_combine(hash, v.position.z);
|
||||
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
template<class XMesh>
|
||||
void updateXMeshVertices(XMesh *pMesh, std::vector<int> &uniqueVertices) {
|
||||
// replace vertex data with the unique data sets
|
||||
@@ -208,7 +267,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
|
||||
}
|
||||
}
|
||||
// a map that maps a vertex to its new index
|
||||
std::map<Vertex, int> vertex2Index = {};
|
||||
std::unordered_map<Vertex, int, HashVertex, CompareVerticesAlmostEqual> vertex2Index = {};
|
||||
// we can not end up with more vertices than we started with
|
||||
// Now check each vertex if it brings something new to the table
|
||||
int newIndex = 0;
|
||||
|
||||
Reference in New Issue
Block a user