JoinIdenticalVertices: Performance optimizations by Krishty („Fuck the System”). Yields a 9x speedup in first benchmarks with meshes > 2k triangles.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@780 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2010-07-11 23:07:11 +00:00
parent 9e8a9586b3
commit a9fd02c14e
4 changed files with 160 additions and 12 deletions

View File

@@ -127,10 +127,12 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
std::vector<Vertex> uniqueVertices;
uniqueVertices.reserve( pMesh->mNumVertices);
// For each vertex the index of the vertex it was replaced by.
// For each vertex the index of the vertex it was replaced by.
// Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
// whether a new vertex was created for the index (true) or if it was replaced by an existing
// unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
// branching performance.
std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
// for each vertex whether it was replaced by an existing unique vertex (true) or a new vertex was created for it (false)
std::vector<bool> isVertexUnique( pMesh->mNumVertices, false);
// A little helper to find locally close vertices faster.
// Try to reuse the lookup table from the last step.
@@ -180,7 +182,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
Vertex v(pMesh,a);
// collect all vertices that are close enough to the given position
vertexFinder->FindPositions( v.position, posEpsilonSqr, verticesFound);
vertexFinder->FindIdenticalPositions( v.position, verticesFound);
unsigned int matchIndex = 0xffffffff;
// check all unique vertices close to the position if this vertex is already present among them
@@ -188,9 +190,8 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
const unsigned int vidx = verticesFound[b];
const unsigned int uidx = replaceIndex[ vidx];
if( uidx == 0xffffffff || !isVertexUnique[ vidx]) {
if( uidx & 0x80000000)
continue;
}
const Vertex& uv = uniqueVertices[ uidx];
// Position mismatch is impossible - the vertex finder already discarded all non-matching positions
@@ -239,15 +240,13 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
if( matchIndex != 0xffffffff)
{
// store where to found the matching unique vertex
replaceIndex[a] = matchIndex;
isVertexUnique[a] = false;
replaceIndex[a] = matchIndex | 0x80000000;
}
else
{
// no unique vertex matches it upto now -> so add it
replaceIndex[a] = (unsigned int)uniqueVertices.size();
uniqueVertices.push_back( v);
isVertexUnique[a] = true;
}
}
@@ -331,7 +330,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
{
aiFace& face = pMesh->mFaces[a];
for( unsigned int b = 0; b < face.mNumIndices; b++) {
face.mIndices[b] = replaceIndex[face.mIndices[b]];
face.mIndices[b] = replaceIndex[face.mIndices[b]] & ~0x80000000;
}
}
@@ -346,7 +345,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
{
const aiVertexWeight& ow = bone->mWeights[b];
// if the vertex is a unique one, translate it
if( isVertexUnique[ow.mVertexId])
if( !(replaceIndex[ow.mVertexId] & 0x80000000))
{
aiVertexWeight nw;
nw.mVertexId = replaceIndex[ow.mVertexId];