• Advertisement
Sign in to follow this  

[Cal3D] Matching bone rotation

This topic is 4335 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone, I've been trying for a few days to attach an object to the Cal3D bones. (More specific, the right hand). I thought things were going well. The translation was easy. But the rotation. Why could it be that hard. I've spent an enormous amount of time on it, and still it does not work. My code can be found here as well (below), it might be useful to other people. Cal3D documentation is very sparse, and alsost no information can be found on the net. Now, I hope someone can give advice how to fix the rotation. Cal3D has been used in so many commercial games, but there is no single piece of examples available made by other people. Strange. Can anyone please shed some light on how to fix the rotation issue? Many many thanks in advance!
int boneId = mesh->m_calModel->getSkeleton()->getCoreSkeleton()->getCoreBoneId("Bip01 R Hand");
	if (boneId > -1)
	{
		D3DXMATRIX matRot, matWorld ,matObjectTrans;
		D3DXMATRIX matBoneRotationMatrix, matBoneTranslation;
		D3DXMATRIX matCorrect;

		D3DXMatrixIdentity(&matWorld);
		D3DXMatrixIdentity(&matObjectTrans);
		D3DXMatrixIdentity(&matBoneTranslation);
		

		//Bip01 L Hand
		CalBone* bone = mesh->m_calModel->getSkeleton()->getBone(boneId);
		CalVector translationBoneSpace = bone->getTranslationAbsolute();

		//Translate the object to the bone position
		D3DXMatrixTranslation(&matBoneTranslation, translationBoneSpace.x,translationBoneSpace.y,translationBoneSpace.z);
		
		//Translate matrix to object position:
		D3DXMatrixTranslation(&matObjectTrans, vPos.x,vPos.y,vPos.z);

		//Apply rotation correction:
		D3DXMatrixRotationYawPitchRoll(&matCorrect, 0.0f,  D3DXToRadian(90.0f), 0.0f);
		D3DXMATRIX mat2;
		D3DXMatrixRotationYawPitchRoll(&mat2, 0.0f,  0.0f, D3DXToRadian(90.0f));

		matWorld = matBoneRotationMatrix * matCorrect * mat2 *  matBoneTranslation * matObjectTrans; //  * matModelRotation * matObjectTrans;

Next to above code, I have tried iterating through all the parents too, with both relative and absolute coordinates. No luck. I have tried the TransFormMatrix(), no luck. Hence I'm messing around with correction matrices, playing with every single x,yz, z,y,x, y,x,z coordinate version, and I have tried every single angle of my 3D mesh. I amm totally clueless. I'm out of suggestions. :-(

Share this post


Link to post
Share on other sites
Advertisement
Hm, no one with any ideas? I'm so suprised that there are so many users, while no one ever seems to write a word about it except for problems. :)

Share this post


Link to post
Share on other sites
I don't know much about cal3d, and I didn't study your code too hard, but general advice when you're having rotation trouble includes the following:

1. Make sure you're translating and rotating in the right order. It may be exactly opposite of what you think it is.
2. Make sure you're rotating about the right axes in the right order.

Share this post


Link to post
Share on other sites
Hi!

Thanks for your reply. Unfortunately, I think I have tried every single combination possible. I guess I could try to seperate the Quaternion values somehow and multiply these in all kinds of diferent orders. I'm beyond clueless, and thinking of ditching the problem for a few weeks. Unfortunately, this is something which is quite a requirement in my game.

Share this post


Link to post
Share on other sites
I don't know Cal3D, but if you want to attach an object to another object in a hierarchy you have to use forward kinematics.
This is very easy. What you need to know is the following information:

1.) The world/absolute matrix of the Bip01 R Hand node.
2.) The local/relative matrix of the attachment (say a gun).

Now to calculate the world/absolute matrix of the attachment, which you use for rendering, you do:


Matrix finalGunMatrix = bip01RHandMatrix * localAttachmentMatrix;


It is also possible that you have to multiply in the opposite order.

To calculate the local space transform from a translation and rotation for the gun, you do something like:


Matrix localAttachmentMatrix = RotationMatrix(rotation) * TranslationMatrix(translation);


You can also just build a rotation matrix and set the translation row or column directly after you built the rotation matrix.

Hope this helps.

Cheers,
- John

Share this post


Link to post
Share on other sites
We use Cal3d for Ancient Galaxy, and we had some fun with this as well.

Don't have my code handy right now, but I believe the trick is to get the absolute rotation, which goes from the root node directly to the local bone space. Then you first apply your dude's main rotation, then this absolute rotation to get into local bone space. Then you can place the object in local space, then get the inverse of the combined matrix to get back to world space.

We used quaternions for the rotations, so I can't comment on doing it with Euler angles.

Share this post


Link to post
Share on other sites
Between its definition and its use for calculating MatWorld, I don't see any occurence of matBoneRotationMatrix. Where is it initialized?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement