From 74af523b3ef6a68fa07749ac974d4fd51c6324e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20R=C3=B6sner?= Date: Thu, 12 Jan 2023 13:13:46 +0100 Subject: [PATCH] Generalize JoinVerticesProcess for multiple UV and color channels --- code/PostProcessing/JoinVerticesProcess.cpp | 49 +++++++++++++-------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/code/PostProcessing/JoinVerticesProcess.cpp b/code/PostProcessing/JoinVerticesProcess.cpp index ef5999875..f752ed0eb 100644 --- a/code/PostProcessing/JoinVerticesProcess.cpp +++ b/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 { //template specialization for std::equal_to for Vertex template<> struct std::equal_to { + 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 vertex2Index; + // a map that maps a vertex to its new index + const auto numBuckets = pMesh->mNumVertices; + const auto hasher = std::hash(); + const auto comparator = std::equal_to( + pMesh->GetNumUVChannels(), + pMesh->GetNumColorChannels()); + std::unordered_map 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