Kenneth Gorking, on 21 January 2012 - 09:15 AM, said:
The aiProcess_LimitBoneWeights specifies how many bones should at most affect a single vertex, but what you are looking at, is how many different vertices each bone is affecting, so you are looking at it backwards
If you want to be totally sure, try this (untested) code:
std::vector<unsigned int> vertexBones(pMesh->mNumVertices, 0);
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
float w = pMesh->mBones[i]->mWeights[j].mWeight;
if(w==0.0f) {
continue;
}
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
vertexBones[vid]++;
assert(vertexBones[vid] < 4);
}
}
Even if with some delay I would like to thank you all for your help.
It got this long because in the meantime I figured it out how to extract data from assimp and I've got skinning working.
But I'm not sure about the limit bone weights thing, because I see some artifacts while the animation is playing and I wouldn't like to think that the approximation that assimp does to limi the weights to, say, 4 is too coarse.
btw the code that I use to reconstruct bone indices into vertex, for me looks like this snippet
//build bones to vertex association
struct boneIndexToVertex_t{
unsigned int boneId[4];
float weight[4];
int currentId;
};
boneIndexToVertex_t* boneIndexToVertex = NULL;
if( mesh->HasBones() && (optImport & OPT_ANIMATIONS_DATA) ){
boneIndexToVertex = new boneIndexToVertex_t[mesh->mNumVertices];
memset(boneIndexToVertex,0,sizeof(boneIndexToVertex_t)*mesh->mNumVertices);
for(unsigned int k=0;k<mesh->mNumBones;++k){
const aiBone* pBone = mesh->mBones[k];
for(unsigned int j=0;j<pBone->mNumWeights;++j){
unsigned int boneIndex = mAnimationMgr.mAiBoneToIdMap[pBone];
unsigned int vertexId = pBone->mWeights[j].mVertexId;
float weight = pBone->mWeights[j].mWeight;
unsigned int id = boneIndexToVertex[vertexId].currentId++;
assert(id<4);
boneIndexToVertex[vertexId].boneId[id] = boneIndex;
boneIndexToVertex[vertexId].weight[id] = weight;
}
}
}
Could that depend on the fact that I don't check if the wieght is 0 (as you do in your code)? But it shouldn't be a problem I think since that will evaluate the whole thing to 0 in the shader when I'll perform skinning...
Any thoughts ? If it can help I could try to produce a movie showing the artifacts ... they are not terribly bad but something let me think that weights could be skrewed somewhere ...
thanks in advance