Jump to content


Extract Bone Infos from ASSIMP


13 replies to this topic

#1 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 20 January 2012 - 12:26 PM

Hi all,

I'm in the process of extracting bone information using ASSIMP.

I've specified the flag aiProcess_LimitBoneWeights but it looks like is not limiting them to 4. Infact they keep being more than 100 !!! Or maybe I'm extracting them in the wrong way.

Btw here is a small snippet of my exporter (it should look for the indices to vertices to reconstruct bone - vertex association):

if(mesh->HasBones()){

			out << "animation_begin" << endl;

			for(unsigned int i=0;i<mesh->mNumBones;++i){
				bone = mesh->mBones[i];
				out << std::string(bone->mName.data) << " ";
				for(unsigned int j = 0;j<bone->mNumWeights;++j){
					aiVertexWeight vertWeight = bone->mWeights[j];
					out << "("<< vertWeight.mVertexId << ", " << vertWeight.mWeight << ")" << " ";
				}				


				out << endl;
			}

			out << "animation_end" << endl;
		}

In the end if someone has already went through all of that using ASSIMP, I'll be more than happy to understand how extract bones for bind pose and how to animate the model.

Thanks a lot in advance

#2 David Gallagher

    New Member

  • Members
  • PipPip
  • 69 posts

Posted 20 January 2012 - 08:34 PM

I myself havn't gotten to the animation side of assimp yet, but I found a project that might really help at http://dx11experiments.codeplex.com/ (source code section), I've had a quick glance at it and might be useful in sorting this out, probably start looking at his MeshFactory.cpp. Hope it helps as I'm hopeing it will help me :).

#3 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 21 January 2012 - 09:15 AM

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);
  }
}

"Stupid bug! You go squish now!!" - Homer Simpson

#4 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 31 January 2012 - 02:58 PM

View PostKenneth 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

#5 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 31 January 2012 - 03:44 PM

It's doubtful that the weights are screwed, it is more likely that some weights are being removed which had a significant impact on the vertices movement, and when they were removed, it started looking weird.

Maybe you can try the aiProcess_SplitByBoneCount flag, and see if that helps things. If it doesn't, you need to manually corect the model in a modeling program :mellow:
"Stupid bug! You go squish now!!" - Homer Simpson

#6 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 31 January 2012 - 03:52 PM

View PostKenneth Gorking, on 31 January 2012 - 03:44 PM, said:

It's doubtful that the weights are screwed, it is more likely that some weights are being removed which had a significant impact on the vertices movement, and when they were removed, it started looking weird.

Maybe you can try the aiProcess_SplitByBoneCount flag, and see if that helps things. If it doesn't, you need to manually corect the model in a modeling program :mellow:

This sounds strange since everyone wants to do hardware skinning and we know we have to necessarily limit the bone count to 4 in the vertex input layout ... So I wouldn't expect any problem :/ ... unless you do skinning on the cpu ... which I would avoid to do ...
btw I'll try that flag and I'll let you know ... in the meantime thanks

#7 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 31 January 2012 - 03:54 PM

View PostSuperPixel, on 31 January 2012 - 03:52 PM, said:

This sounds strange since everyone wants to do hardware skinning and we know we have to necessarily limit the bone count to 4 in the vertex input layout ... So I wouldn't expect any problem :/ ... unless you do skinning on the cpu ... which I would avoid to do ...
btw I'll try that flag and I'll let you know ... in the meantime thanks

aiProcess_SplitByBoneCount doesn't exist ....

#8 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 31 January 2012 - 03:58 PM

It does in mine, and I just did a svn-update to be sure they hadn't removed it. I'm on revision 1124, and the flag is located in include\aiPostProcess.h. Maybe you need to update your copy?
"Stupid bug! You go squish now!!" - Homer Simpson

#9 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 31 January 2012 - 04:07 PM

I do not have it under subversion ... I have the website version

#10 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 31 January 2012 - 04:10 PM

View PostSuperPixel, on 31 January 2012 - 04:07 PM, said:

I do not have it under subversion ... I have the website version

Nevermind I've found the repo link for anonimous user and I've also checked the aiPostProcess.h header and yes they added it recently ... I might have a go with that one

Thanks

#11 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 01 February 2012 - 09:54 AM

View PostKenneth Gorking, on 31 January 2012 - 03:44 PM, said:

It's doubtful that the weights are screwed, it is more likely that some weights are being removed which had a significant impact on the vertices movement, and when they were removed, it started looking weird.

Maybe you can try the aiProcess_SplitByBoneCount flag, and see if that helps things. If it doesn't, you need to manually corect the model in a modeling program :mellow:

I've tried with that flag, but I've got the same problems. I think I should look for a simple animated model with just 4 bones per vertex... do you know about any of them ? It should preferably be a Collada format (*.dae)

thanks

#12 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 01 February 2012 - 11:49 AM

View PostSuperPixel, on 01 February 2012 - 09:54 AM, said:

I've tried with that flag, but I've got the same problems. I think I should look for a simple animated model with just 4 bones per vertex... do you know about any of them ? It should preferably be a Collada format (*.dae)

thanks
I can't say that I do, but I think there are some test files in assimp. There might be one with animation, if you are lucky.
"Stupid bug! You go squish now!!" - Homer Simpson

#13 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 01 February 2012 - 05:57 PM

View PostKenneth Gorking, on 01 February 2012 - 11:49 AM, said:

I can't say that I do, but I think there are some test files in assimp. There might be one with animation, if you are lucky.

I debugged a bugged animation frame and I've found some bone matrices to have:

-1.#IND000

in all their 16 elements !!!!

for what reason could that happen ?

#14 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 02 February 2012 - 04:52 PM

View PostKenneth Gorking, on 01 February 2012 - 11:49 AM, said:

I can't say that I do, but I think there are some test files in assimp. There might be one with animation, if you are lucky.

Finally I've solved ! I wasn't checking the calculation of the w component of the quaternion that was giving me the sqrt of a negative value that was producing -1.#IND000!





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users