Added "ImproveCacheLocality"-Step; Added Unit tests (3 at the moment); Fixed hp spelling errors.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@68 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2008-07-22 22:52:16 +00:00
parent 04fe342441
commit e8511e89ff
45 changed files with 2324 additions and 152 deletions

View File

@@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../include/aiPostProcess.h"
#include "../include/aiMesh.h"
#include "../include/aiScene.h"
#include "../include/aiAssert.h"
#include "../include/DefaultLogger.h"
using namespace Assimp;
@@ -122,11 +123,14 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
}
// now cut the weight count if it exceeds the maximum
bool bChanged = false;
for( WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit)
{
if( vit->size() <= mMaxWeights)
continue;
bChanged = true;
// more than the defined maximum -> first sort by weight in descending order. That's
// why we defined the < operator in such a weird way.
std::sort( vit->begin(), vit->end());
@@ -142,28 +146,71 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
it->mWeight /= sum;
}
// rebuild the vertex weight array for all bones
typedef std::vector< std::vector< aiVertexWeight > > WeightsPerBone;
WeightsPerBone boneWeights( pMesh->mNumBones);
for( unsigned int a = 0; a < vertexWeights.size(); a++)
if (bChanged)
{
const std::vector<Weight>& vw = vertexWeights[a];
for( std::vector<Weight>::const_iterator it = vw.begin(); it != vw.end(); ++it)
boneWeights[it->mBone].push_back( aiVertexWeight( a, it->mWeight));
}
// and finally copy the vertex weight list over to the mesh's bones
for( unsigned int a = 0; a < pMesh->mNumBones; a++)
{
const std::vector<aiVertexWeight>& bw = boneWeights[a];
aiBone* bone = pMesh->mBones[a];
// ignore the bone if no vertex weights were removed there
if( bw.size() == bone->mNumWeights)
continue;
// rebuild the vertex weight array for all bones
typedef std::vector< std::vector< aiVertexWeight > > WeightsPerBone;
WeightsPerBone boneWeights( pMesh->mNumBones);
for( unsigned int a = 0; a < vertexWeights.size(); a++)
{
const std::vector<Weight>& vw = vertexWeights[a];
for( std::vector<Weight>::const_iterator it = vw.begin(); it != vw.end(); ++it)
boneWeights[it->mBone].push_back( aiVertexWeight( a, it->mWeight));
}
// copy the weight list. should always be less weights than before, so we don't need a new allocation
assert( bw.size() < bone->mNumWeights);
bone->mNumWeights = (unsigned int) bw.size();
memcpy( bone->mWeights, &bw[0], bw.size() * sizeof( aiVertexWeight));
// and finally copy the vertex weight list over to the mesh's bones
std::vector<bool> abNoNeed(pMesh->mNumBones,false);
bChanged = false;
for( unsigned int a = 0; a < pMesh->mNumBones; a++)
{
const std::vector<aiVertexWeight>& bw = boneWeights[a];
aiBone* bone = pMesh->mBones[a];
// ignore the bone if no vertex weights were removed there
// FIX (Aramis, 07|22|08)
// NO! we can't ignore it in this case ... it is possible that
// the number of weights did not change, but the weight values did.
// if( bw.size() == bone->mNumWeights)
// continue;
// FIX (Aramis, 07|21|08)
// It is possible that all weights of a bone have been removed.
// This would naturally cause an exception in &bw[0].
if ( bw.empty() )
{
abNoNeed[a] = bChanged = true;
continue;
}
// copy the weight list. should always be less weights than before, so we don't need a new allocation
ai_assert( bw.size() <= bone->mNumWeights);
bone->mNumWeights = (unsigned int) bw.size();
::memcpy( bone->mWeights, &bw[0], bw.size() * sizeof( aiVertexWeight));
}
if (bChanged)
{
// the number of new bones is smaller than before, so we can
// reuse the old array, too.
aiBone** ppcCur = pMesh->mBones;
aiBone** ppcSrc = ppcCur;
for (std::vector<bool>::const_iterator
iter = abNoNeed.begin();
iter != abNoNeed.end() ;++iter)
{
if (*iter)
{
delete *ppcSrc;
--pMesh->mNumBones;
}
else *ppcCur++ = *ppcSrc;
++ppcSrc;
}
}
}
}