Răsfoiți Sursa

Generalize JoinVerticesProcess for multiple UV and color channels

Daniel Rösner 2 ani în urmă
părinte
comite
74af523b3e
1 a modificat fișierele cu 30 adăugiri și 19 ștergeri
  1. 30 19
      code/PostProcessing/JoinVerticesProcess.cpp

+ 30 - 19
code/PostProcessing/JoinVerticesProcess.cpp

@@ -105,7 +105,11 @@ void JoinVerticesProcess::Execute( aiScene* pScene) {
 
 namespace {
 
-bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex) {
+bool areVerticesEqual(
+    const Vertex &lhs,
+    const Vertex &rhs,
+    unsigned numUVChannels,
+    unsigned numColorChannels) {
     // A little helper to find locally close vertices faster.
     // Try to reuse the lookup table from the last step.
     const static float epsilon = 1e-5f;
@@ -124,10 +128,6 @@ bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex) {
         return false;
     }
 
-    if ((lhs.texcoords[0] - rhs.texcoords[0]).SquareLength() > squareEpsilon) {
-        return false;
-    }
-
     if ((lhs.tangent - rhs.tangent).SquareLength() > squareEpsilon) {
         return false;
     }
@@ -136,19 +136,18 @@ bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex) {
         return false;
     }
 
-    // Usually we won't have vertex colors or multiple UVs, so we can skip from here
-    // Actually this increases runtime performance slightly, at least if branch
-    // prediction is on our side.
-    if (complex) {
-        for (int i = 0; i < 8; i++) {
-            if (i > 0 && (lhs.texcoords[i] - rhs.texcoords[i]).SquareLength() > squareEpsilon) {
-                return false;
-            }
-            if (GetColorDifference(lhs.colors[i], rhs.colors[i]) > squareEpsilon) {
-                return false;
-            }
+    for (unsigned i = 0; i < numUVChannels; i++) {
+        if ((lhs.texcoords[i] - rhs.texcoords[i]).SquareLength() > squareEpsilon) {
+            return false;
         }
     }
+
+    for (unsigned i = 0; i < numColorChannels; i++) {
+        if (GetColorDifference(lhs.colors[i], rhs.colors[i]) > squareEpsilon) {
+            return false;
+        }
+    }
+
     return true;
 }
 
@@ -241,9 +240,16 @@ struct std::hash<Vertex> {
 //template specialization for std::equal_to for Vertex
 template<>
 struct std::equal_to<Vertex> {
+    equal_to(unsigned numUVChannels, unsigned numColorChannels) :
+            mNumUVChannels(numUVChannels),
+            mNumColorChannels(numColorChannels) {}
     bool operator()(const Vertex &lhs, const Vertex &rhs) const {
-        return areVerticesEqual(lhs, rhs, false);
+        return areVerticesEqual(lhs, rhs, mNumUVChannels, mNumColorChannels);
     }
+
+private:
+    unsigned mNumUVChannels;
+    unsigned mNumColorChannels;
 };
 // now start the JoinVerticesProcess
 int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
@@ -316,8 +322,13 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
             uniqueAnimatedVertices[animMeshIndex].reserve(pMesh->mNumVertices);
         }
     }
-    // a map that maps a vertix to its new index
-    std::unordered_map<Vertex,int> vertex2Index;
+    // a map that maps a vertex to its new index
+    const auto numBuckets = pMesh->mNumVertices;
+    const auto hasher = std::hash<Vertex>();
+    const auto comparator = std::equal_to<Vertex>(
+            pMesh->GetNumUVChannels(),
+            pMesh->GetNumColorChannels());
+    std::unordered_map<Vertex, int> vertex2Index(numBuckets, hasher, comparator);
     // we can not end up with more vertices than we started with
     vertex2Index.reserve(pMesh->mNumVertices);
     // Now check each vertex if it brings something new to the table